From 5df76aff8f128d592ca0d2e7c4d354b369a2e20c Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Tue, 15 Nov 2022 12:15:01 +0100 Subject: [PATCH 01/38] Update and rename QoD_Stable_Latency_API.md to QoD_API.md --- .../{QoD_Stable_Latency_API.md => QoD_API.md} | 73 ++++++++++--------- 1 file changed, 38 insertions(+), 35 deletions(-) rename documentation/API_documentation/{QoD_Stable_Latency_API.md => QoD_API.md} (55%) diff --git a/documentation/API_documentation/QoD_Stable_Latency_API.md b/documentation/API_documentation/QoD_API.md similarity index 55% rename from documentation/API_documentation/QoD_Stable_Latency_API.md rename to documentation/API_documentation/QoD_API.md index 04d5855cf7..bd0bbab1c5 100644 --- a/documentation/API_documentation/QoD_Stable_Latency_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -1,39 +1,36 @@ # Overview -The Quality-On-Demand (QoD) API for stable latency provides programmable interface for developers and other users (capabilities consumers) to specify stable data-transfer latency managed by Telco networks without necessity to have in-depth knowledge of the 4G/5G system complexity by abstracting the internal complexity of telecom systems [1]. +The Quality-On-Demand (QoD) API provides programmable interface for developers and other users (capabilities consumers) to specify stable data-transfer latency or throughput managed by Telco networks without necessity to have in-depth knowledge of the 4G/5G system complexity by abstracting the internal complexity of telecom systems [1]. ## 1\. Introduction -Industrial (IoT), VR/Gaming, broadcasting, autonomous driving and many others scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable latency (reduced jitter) from the network can improve user experience. +Industrial (IoT), VR/Gaming, broadcasting, autonomous driving and many others scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable latency (reduced jitter) or stable throughput from the network can improve user experience. -The QoD latency API offers the application developers the capability to request for stable latency (reduced jitter) for a specified App-Flow between User Equipment (application clients) and Application Servers (backend services). The developer has a pre-defined set of QoS\_Profiles which he could choose from depending on his latency requirements. +The QoD API offers the application developers the capability to request for stable latency (reduced jitter) or throughput for a specified App-Flow between User Equipment (application clients) and Application Servers (backend services). The developer has a pre-defined set of QoS\_Profiles which they could choose from depending on their latency or throughput requirements. -QoD_LM +QoD_LM ## 2\. Quick Start -The usage of the stable latency API is based on QoS sessions, which can be created (based on available QoS profiles), queried and deleted. +The usage of the API is based on QoS sessions, which can be created (based on available QoS profiles), queried and deleted. The deletion of a requested session can be triggered by the user or can be triggered automatically. The automatic process is triggered either when the user specified duration has reached its limit or default session expiration time has been reached (witihin reference implementation set to 24hrs). Before starting to use the API, the developer needs to know about the below specified details: **Base-URL** -The RESTful Stable Throughput API endpoint, for example [**https://telekom-api.developer.telekom.com/5g-latency**](https://telekom-api.developer.telekom.com/5g-throughput) +The RESTful Stable Throughput API endpoint, for example [**https://telekom-api.developer.telekom.com/5g-qod**](https://telekom-api.developer.telekom.com/5g-qod) **Authentication** Configure security access keys such as OAuth 2.0 client credentials to be used by Client applications which will invoke the QoD API. **QoS Profile** -Define latency requirements of the application and identify QoS profile class which maps into the required performance category. +Define latency or throughput requirements of the application and identify QoS profile class which maps into the required performance category. **App-Flow** -Describes the precise flow the developer wants to prioritize and have stable latency for. This flow is described using source and destination IP addresses, ports and protocols with flow direction. - -**Duration** -Define the number of seconds for which the QoD session should be created. This parameter is optional and if not specified, the session is either deleted on user request or if default expiration limit has been reached (24 hours in reference implmentation). +Describes the precise flow the developer wants to prioritize and have stable latency or throughput for. This flow is described using source and destination IP addresses and ports/port-ranges. **Notification URL and token** -Developers have a chance to specify callback URL on which notifications (eg. session termination) regarding the session can be received from the service provider. This is also an optional parameter. +Developers have a chance to specify callback URL on which notifications (eg. session termination) regarding the session can be received from the service provider. This is an optional parameter. Sample API invocations are presented in Section 4.5. @@ -45,45 +42,51 @@ In this method the API invoker client is registered as a confidential client wit ## 4\. API Documentation -### 4.1 Details +### 4.1 API Version + +0.8.0 + +### 4.2 Details -The usage of the QoD latency API is based on QoS profile classes and parameters which define App-Flows. -Based on the API, QoS sessions can be created, queried, and deleted. Once an offered QoS profile latency class is requested, application users get a prioritized service with stable latency even in the case of congestion.The QoD latency API has the following characteristics: +The usage of the QoD API is based on QoS profile classes and parameters which define App-Flows. +Based on the API, QoS sessions can be created, queried, and deleted. Once an offered QoS profile class is requested, application users get a prioritized service with stable latency or throughput even in the case of congestion.The QoD API has the following characteristics: -* A specified App-Flow is prioritized to ensure stable latency for that flow -* The prioritized App-Flow is described by providing additional information such as protocols, ports, uplink/downlink direction of flow etc. -* Stable latency is requested by selecting from the list of QoS profiles made available by the service provider (e.g. LOW) to map latency requirements -* The developer can optionally specify the duration for which he needs the prioritized App-flow +* A specified App-Flow is prioritized to ensure stable latency or throughput for that flow +* The prioritized App-Flow is described by providing information such as source & destination IP address and port/port-ranges +* Stable latency or throughput is requested by selecting from the list of QoS profiles made available by the service provider (e.g. QOS_E) to map latency requirements * The developer can optionally also specify callback URL on which notifications for the session can be sent Following diagram shows the interaction between different components
-QoD_LM +QoD_LM The below table shows sample QoS profiles and are subject to service provider customizations. This sample is taken from the agreed sample (example) set from the Camara-project [2]. | **QoD latency profile** | **Details** | | ------------------- | ------- | -| LOW\_Latency | App-Flow with stable "latency" under congestion (e.g. throughput up-to 2Mbps) | +| QOS\_E | Enhanced communication class with with stable latency under congestion (e.g. throughput up-to 2Mbps) | +| QOS\_S | Small class of throughput profile - for example DL (Downlink) up-to 10Mbps | +| QOS\_M | Medium class of throughput profile - for example DL (Downlink) up-to 30Mbps | +| QOS\_L | Large class of throughput profile - for example DL (Downlink) up-to 100Mbps | -### 4.2 Endpoint Definitions +### 4.3 Endpoint Definitions -Following table defines API endpoints of exposed REST based for QoD latency management operations. +Following table defines API endpoints of exposed REST based for QoD management operations. | **Endpoint** | **Operation** | **Description** | | -------- | --------- | ----------- | -| POST
\/qod-latency-api/v0/sessions | **Create Latency Session** | Create QoS Session to manage latency priorities | -| GET
\/qod-latency-api/v0/sessions/{sessionId} | **Query for Latency** | Querying for QoS "latency" session information details | -| DELETE
\/qod-latency-api/v0/sessions/{sessionId} | **Delete Latency Session** | Deleting a QoS "latency" session | +| POST
\/qod-api/v0/sessions | **Create QoD Session** | Create QoS Session to manage latency/throughput priorities | +| GET
\/qod-api/v0/sessions/{sessionId} | **Query for QoD Session** | Querying for QoD session information details | +| DELETE
\/qod-api/v0/sessions/{sessionId} | **Delete QoD Session** | Deleting a QoD session |
-#### QoD Create Latency QoS Session Operation +#### QoD Create QoS Session Operation -| **Create Latency QoS Session** | +| **Create QoD Session** | | -------------------------- | -| **HTTP Request**
POST \/qod-latency-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \
[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**protocolIn:** The used transport protocol for the uplink.
TCP - TCP protocol
UDP - UDP protocol
ANY - all protocols
**protocolOut :** The used transport protocol for the downlink.
TCP - TCP protocol
UDP - UDP protocol
ANY - all protocols
**qos:** Qualifier for the requested latency profile.
LOW\_LATENCY - to request the stable latency
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**protocolIn:** The used transport protocol for the uplink.
**protocolOut:** The used transport protocol for the downlink.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** | +| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \
[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**protocolIn:** The used transport protocol for the uplink.
TCP - TCP protocol
UDP - UDP protocol
ANY - all protocols
**protocolOut :** The used transport protocol for the downlink.
TCP - TCP protocol
UDP - UDP protocol
ANY - all protocols
**qos:** Qualifier for the requested latency/throughput profile.
LOW\_LATENCY - to request the stable latency
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**protocolIn:** The used transport protocol for the uplink.
**protocolOut:** The used transport protocol for the downlink.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** |
#### QoD Query for Latency QoS Session @@ -99,7 +102,7 @@ Following table defines API endpoints of exposed REST based for QoD latency mana | ---------------------------- | | **HTTP Request**
DELETE\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that need to terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found | -### 4.3 Errors +### 4.4 Errors Since CAMARA QoD API is based on REST design principles and blueprints, well defined HTTP status codes and families specified by community are followed [4]. @@ -119,11 +122,11 @@ Following table provides an overview of common error names, codes and messages a | 8 | Session with same parameters already exists | 409 | "Found session \ already active until \" | | 9 | Service unavailable | 503 | “Internal error due to requrired telco service unvailability" | -### 4.4 Policies +### 4.5 Policies N/A -### 4.5 Code Snippets +### 4.6 Code Snippets
Snippet 1, elaborates REST based API call with "*curl"* to create a QoS session for sample streaming service with following parameters: @@ -142,15 +145,15 @@ Snippet 2, elaborates sample QoS notification "SESSION\_TERMINATION" message dis | ------------------------------------------ | | {
"sessionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "event": "SESSION\_TERMINATED"
} | -### 4.6 FAQ's +### 4.7 FAQ's (FAQs will be added in a later version of the documentation) -### 4.7 Terms +### 4.8 Terms N/A -### 4.8 Release Notes +### 4.9 Release Notes N/A From 5a44d51473d3814f319f109dbef057dc839641db Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Tue, 15 Nov 2022 12:56:41 +0100 Subject: [PATCH 02/38] Add files via upload --- .../API_documentation/resources/QoD_details.PNG | Bin 0 -> 28084 bytes .../resources/QoD_overview.PNG | Bin 0 -> 15142 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 documentation/API_documentation/resources/QoD_details.PNG create mode 100644 documentation/API_documentation/resources/QoD_overview.PNG diff --git a/documentation/API_documentation/resources/QoD_details.PNG b/documentation/API_documentation/resources/QoD_details.PNG new file mode 100644 index 0000000000000000000000000000000000000000..0547d67fc2658a60c935f5d9af2718765770c750 GIT binary patch literal 28084 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

DnVYhBXOfIe$$_LYBWZH?MFk~h1iKOp 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 literal 0 HcmV?d00001 diff --git a/documentation/API_documentation/resources/QoD_overview.PNG b/documentation/API_documentation/resources/QoD_overview.PNG new file mode 100644 index 0000000000000000000000000000000000000000..006bb2434b00516b3b53fb94fde9fda63ddb1442 GIT binary patch literal 15142 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 Date: Tue, 15 Nov 2022 13:44:51 +0100 Subject: [PATCH 03/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 57 ++++++++++++---------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index bd0bbab1c5..fad3b36a75 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -8,7 +8,7 @@ Industrial (IoT), VR/Gaming, broadcasting, autonomous driving and many others sc The QoD API offers the application developers the capability to request for stable latency (reduced jitter) or throughput for a specified App-Flow between User Equipment (application clients) and Application Servers (backend services). The developer has a pre-defined set of QoS\_Profiles which they could choose from depending on their latency or throughput requirements. -QoD_LM +QoD_LM ## 2\. Quick Start @@ -18,7 +18,7 @@ The deletion of a requested session can be triggered by the user or can be trigg Before starting to use the API, the developer needs to know about the below specified details: **Base-URL** -The RESTful Stable Throughput API endpoint, for example [**https://telekom-api.developer.telekom.com/5g-qod**](https://telekom-api.developer.telekom.com/5g-qod) +The RESTful QoD API endpoint **Authentication** Configure security access keys such as OAuth 2.0 client credentials to be used by Client applications which will invoke the QoD API. @@ -29,6 +29,9 @@ Define latency or throughput requirements of the application and identify QoS pr **App-Flow** Describes the precise flow the developer wants to prioritize and have stable latency or throughput for. This flow is described using source and destination IP addresses and ports/port-ranges. +**Duration** +Define the number of seconds for which the QoD session should be created. This parameter is optional and if not specified, the session is either deleted on user request or if default expiration limit has been reached (24 hours in reference implementation). + **Notification URL and token** Developers have a chance to specify callback URL on which notifications (eg. session termination) regarding the session can be received from the service provider. This is an optional parameter. @@ -53,18 +56,19 @@ Based on the API, QoS sessions can be created, queried, and deleted. Once an off * A specified App-Flow is prioritized to ensure stable latency or throughput for that flow * The prioritized App-Flow is described by providing information such as source & destination IP address and port/port-ranges +* The developer can optionally specify the duration for which they need the prioritized App-flow * Stable latency or throughput is requested by selecting from the list of QoS profiles made available by the service provider (e.g. QOS_E) to map latency requirements * The developer can optionally also specify callback URL on which notifications for the session can be sent Following diagram shows the interaction between different components
-QoD_LM +QoD_LM The below table shows sample QoS profiles and are subject to service provider customizations. This sample is taken from the agreed sample (example) set from the Camara-project [2]. -| **QoD latency profile** | **Details** | +| **QoD profile** | **Details** | | ------------------- | ------- | | QOS\_E | Enhanced communication class with with stable latency under congestion (e.g. throughput up-to 2Mbps) | | QOS\_S | Small class of throughput profile - for example DL (Downlink) up-to 10Mbps | @@ -86,19 +90,19 @@ Following table defines API endpoints of exposed REST based for QoD management o | **Create QoD Session** | | -------------------------- | -| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \

[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**protocolIn:** The used transport protocol for the uplink.
TCP - TCP protocol
UDP - UDP protocol
ANY - all protocols
**protocolOut :** The used transport protocol for the downlink.
TCP - TCP protocol
UDP - UDP protocol
ANY - all protocols
**qos:** Qualifier for the requested latency/throughput profile.
LOW\_LATENCY - to request the stable latency
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**protocolIn:** The used transport protocol for the uplink.
**protocolOut:** The used transport protocol for the downlink.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** | +| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \
[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**qos:** Qualifier for the requested latency/throughput profile.
LOW\_LATENCY - to request the stable latency
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** |
-#### QoD Query for Latency QoS Session +#### QoD Query for QoS Session -| **Quering QoS Session Latency information** | +| **Quering QoS Session information** | | --------------------------------------- | -| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**protocolIn:** The used transport protocol for the uplink.
**protocolOut:** The used transport protocol for the downlink.
**qos:** Qualifier of the requested Latency profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since unix epoch.

**401:** Un-authorised, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. | +| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested Latency profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since unix epoch.

**401:** Un-authorised, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. |
-#### QoD Delete Latency QoS Session +#### QoD Delete QoS Session -| **Deleting QoS Latency session** | +| **Deleting QoS session** | | ---------------------------- | | **HTTP Request**
DELETE\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that need to terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found | @@ -112,15 +116,18 @@ Following table provides an overview of common error names, codes and messages a | No | Error Name | Error Code | Error Message | | --- | ---------- | ---------- | ------------- | -| 1 | Invalid port(s) | 400 | "Ports specification not valid | -| 2 | Invalid protocol | 400 | "Validation failed for parameter: protocol" | -| 3 | Invalid QoS profile | 400 | "Validation failed for parameter: QoS-profile" | -| 4 | Invalid IP address (format) | 400 | "Validation failed for parameter: IP-addr" | -| 5 | Invalid duration | 400 | "Validation failed for parameter: Session duration" | -| 6 | Unauthorized | 401 | "Un-authorized to invoke operation" | -| 7 | Forbidden | 403 | "Forbidden to invoke operation" | -| 8 | Session with same parameters already exists | 409 | "Found session \ already active until \" | -| 9 | Service unavailable | 503 | “Internal error due to requrired telco service unvailability" | +|1 |400 | INVALID_INPUT | "Expected property is missing: ueId.msisdn" | +|2 |400 | INVALID_INPUT | "Expected property is missing: ueId.ipv4addr" | +|3 |400 | INVALID_INPUT | "Expected property is missing: ueId.ipv4addr or ueId.ipv6addr" | +|4 |400 | INVALID_INPUT | "Expected property is missing: uePorts" | +|5 |400 | INVALID_INPUT | "Expected property is missing: qos" | +|6 |400 | INVALID_INPUT | "Ranges not allowed: uePorts" | +|7 |401 | UNAUTHORIZED | "Authorization to invoke operation" | +|8 |403 | FORBIDDEN | "Operation not allowed" | +|9 |404 | NOT_FOUND | "Session Id does not exist" | +|10 |409 | CONFLICT | "Another session is created for the same UE" | +|11 |500 | INTERNAL | "Session could not be created" | +|12 |503 | SERVICE_UNAVAILABLE | "Service unavailable" | ### 4.5 Policies @@ -130,20 +137,20 @@ N/A
Snippet 1, elaborates REST based API call with "*curl"* to create a QoS session for sample streaming service with following parameters: -* Latency QoS session with 1H duration and QoS-profile "LOW\_Latency" mapping, -* App-Flow is specified for UDP protocol with UE-Terminal IP address (ueAddr=10.0.0.1), Application server network (asAddr=54.204.25.0/28) and Port number (asPorts=33001). +* Latency QoS session with QoS-profile "QOS_E" mapping, +* App-Flow is specified for UE-Terminal IP address (ueAddr=10.0.0.1), Application server network (asAddr=54.204.25.0/28) and Port number (asPorts=33001). Please note, the credentials for API authentication purposes need to be adjusted based on target security system configuration. -| Snippet 1. Create QoS session to manage latency | +| Snippet 1. Create QoS session | | ----------------------------------------------- | -| curl -X 'POST' `https://sample-base-url/qod-latency-api/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"duration": 3600,
"ueAddr": "10.0.0.1",
"asAddr": "54.204.25.0/28",
"asPorts": "33001",
"protocolOut": "UDP",
"qos": "LOW\_Latency",
"notificationUri": `https://your-callback-server.com/notifications`,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' | +| curl -X 'POST' `https://sample-base-url/qod-api/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"ueAddr": "10.0.0.1",
"asAddr": "54.204.25.0/28",
"asPorts": "33001",
"qos": "QOS_E",
"notificationUri": `https://your-callback-server.com/notifications`,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' |
-Snippet 2, elaborates sample QoS notification "SESSION\_TERMINATION" message distributed from QoD backend to client callback function. +Snippet 2, elaborates sample QoS notification "SESSION_TERMINATION" message distributed from QoD backend to client callback function. | Snippet 2. Sample QoS session notification | | ------------------------------------------ | -| {
"sessionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "event": "SESSION\_TERMINATED"
} | +| {
"sessionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "event": "SESSION_TERMINATED"
} | ### 4.7 FAQ's From 769972267df3cdcf1059b326fa8cfaf6a2d2b61e Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Tue, 15 Nov 2022 17:17:13 +0100 Subject: [PATCH 04/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index fad3b36a75..5777e7d72c 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -70,10 +70,10 @@ This sample is taken from the agreed sample (example) set from the Camara-projec | **QoD profile** | **Details** | | ------------------- | ------- | -| QOS\_E | Enhanced communication class with with stable latency under congestion (e.g. throughput up-to 2Mbps) | -| QOS\_S | Small class of throughput profile - for example DL (Downlink) up-to 10Mbps | -| QOS\_M | Medium class of throughput profile - for example DL (Downlink) up-to 30Mbps | -| QOS\_L | Large class of throughput profile - for example DL (Downlink) up-to 100Mbps | +| QOS_E | Enhanced communication class with with stable latency under congestion (e.g. throughput up-to 2Mbps) | +| QOS_S | Small class of throughput profile - for example DL (Downlink) up-to 10Mbps | +| QOS_M | Medium class of throughput profile - for example DL (Downlink) up-to 30Mbps | +| QOS_L | Large class of throughput profile - for example DL (Downlink) up-to 100Mbps | ### 4.3 Endpoint Definitions From 557243557853121398519f6f3199f4b7819f5cd4 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Tue, 15 Nov 2022 19:35:57 +0100 Subject: [PATCH 05/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 5777e7d72c..988ffa0946 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -90,7 +90,7 @@ Following table defines API endpoints of exposed REST based for QoD management o | **Create QoD Session** | | -------------------------- | -| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \
[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**qos:** Qualifier for the requested latency/throughput profile.
LOW\_LATENCY - to request the stable latency
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** | +| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \
[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**qos:** Qualifier for the requested latency/throughput profile.
LOW\_LATENCY - to request the stable latency
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** |
#### QoD Query for QoS Session From 0b6addd4e27344501f659a6d3dfd80b29d08ead2 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Tue, 15 Nov 2022 19:39:10 +0100 Subject: [PATCH 06/38] Add files via upload --- .../resources/QoD_overview.PNG | Bin 15142 -> 14712 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/documentation/API_documentation/resources/QoD_overview.PNG b/documentation/API_documentation/resources/QoD_overview.PNG index 006bb2434b00516b3b53fb94fde9fda63ddb1442..b066939cf94a4e752dda4098e0096995c4b885a3 100644 GIT binary patch literal 14712 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 Date: Tue, 15 Nov 2022 19:41:11 +0100 Subject: [PATCH 07/38] Delete QoD_overview.PNG --- .../resources/QoD_overview.PNG | Bin 14712 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 documentation/API_documentation/resources/QoD_overview.PNG diff --git a/documentation/API_documentation/resources/QoD_overview.PNG b/documentation/API_documentation/resources/QoD_overview.PNG deleted file mode 100644 index b066939cf94a4e752dda4098e0096995c4b885a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14712 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 Date: Tue, 15 Nov 2022 19:41:39 +0100 Subject: [PATCH 08/38] Add files via upload --- .../resources/QoD_overview.PNG | Bin 0 -> 14712 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 documentation/API_documentation/resources/QoD_overview.PNG diff --git a/documentation/API_documentation/resources/QoD_overview.PNG b/documentation/API_documentation/resources/QoD_overview.PNG new file mode 100644 index 0000000000000000000000000000000000000000..b066939cf94a4e752dda4098e0096995c4b885a3 GIT binary patch literal 14712 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 Date: Tue, 15 Nov 2022 20:40:47 +0100 Subject: [PATCH 09/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 988ffa0946..88e03c44ae 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -90,14 +90,14 @@ Following table defines API endpoints of exposed REST based for QoD management o | **Create QoD Session** | | -------------------------- | -| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \
[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**qos:** Qualifier for the requested latency/throughput profile.
LOW\_LATENCY - to request the stable latency
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** | +| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \
[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**qos:** Qualifier for the requested latency/throughput profile.
LOW\_LATENCY - to request the stable latency
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** |
#### QoD Query for QoS Session | **Quering QoS Session information** | | --------------------------------------- | -| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested Latency profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since unix epoch.

**401:** Un-authorised, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. | +| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePorts (optional):** The requested port(s) on the user equipment which can be either be specified as ranges or .
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested Latency profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since unix epoch.

**401:** Un-authorised, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. |
#### QoD Delete QoS Session From 6f4098b7fb9b6c91fa26bf916ff8e98e2c2ff936 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Tue, 15 Nov 2022 23:04:21 +0100 Subject: [PATCH 10/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 41 +++++++++++----------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 88e03c44ae..1139045fe7 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -1,19 +1,19 @@ # Overview -The Quality-On-Demand (QoD) API provides programmable interface for developers and other users (capabilities consumers) to specify stable data-transfer latency or throughput managed by Telco networks without necessity to have in-depth knowledge of the 4G/5G system complexity by abstracting the internal complexity of telecom systems [1]. +The Quality-On-Demand (QoD) API provides programmable interface for developers and other users (capabilities consumers) to request stable latency or throughput managed by Telco networks without the necessity to have an in-depth knowledge of the 4G/5G system or the overall complexity of the Telecom Systems [1]. ## 1\. Introduction -Industrial (IoT), VR/Gaming, broadcasting, autonomous driving and many others scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable latency (reduced jitter) or stable throughput from the network can improve user experience. +Industrial (IoT), VR/Gaming, broadcasting, autonomous driving and many others scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable latency (reduced jitter) or stable throughput from the network can improve user experience substantially. -The QoD API offers the application developers the capability to request for stable latency (reduced jitter) or throughput for a specified App-Flow between User Equipment (application clients) and Application Servers (backend services). The developer has a pre-defined set of QoS\_Profiles which they could choose from depending on their latency or throughput requirements. +The QoD API offers the application developers the capability to request for stable latency (reduced jitter) or throughput for a specified App-Flow between User Equipment (application clients) and Application Servers (backend services). The developer has a pre-defined set of Quality of Service (QoS) Profiles which they could choose from depending on their latency or throughput requirements. QoD_LM ## 2\. Quick Start The usage of the API is based on QoS sessions, which can be created (based on available QoS profiles), queried and deleted. -The deletion of a requested session can be triggered by the user or can be triggered automatically. The automatic process is triggered either when the user specified duration has reached its limit or default session expiration time has been reached (witihin reference implementation set to 24hrs). +The deletion of a requested session can be triggered by the user or can be triggered automatically. The automatic process is triggered either when the user specified duration of a QoS session has reached its limit or the default session expiration time has been reached (within an example provider implementation it is set to 24hrs). Before starting to use the API, the developer needs to know about the below specified details: @@ -21,27 +21,27 @@ Before starting to use the API, the developer needs to know about the below spec The RESTful QoD API endpoint **Authentication** -Configure security access keys such as OAuth 2.0 client credentials to be used by Client applications which will invoke the QoD API. +Security access keys such as OAuth 2.0 client credentials used by Client applications to invoke the QoD API. **QoS Profile** -Define latency or throughput requirements of the application and identify QoS profile class which maps into the required performance category. +Latency or throughput requirements of the application mapped to relevant QoS profile class. **App-Flow** -Describes the precise flow the developer wants to prioritize and have stable latency or throughput for. This flow is described using source and destination IP addresses and ports/port-ranges. +The precise IP flow the developer wants to prioritize and have stable latency or throughput for. This flow is described using source and destination IP addresses and ports/port-ranges. **Duration** -Define the number of seconds for which the QoD session should be created. This parameter is optional and if not specified, the session is either deleted on user request or if default expiration limit has been reached (24 hours in reference implementation). +Number of seconds for which the QoD session should be created. This parameter is optional and if not specified, the session is either deleted on user request or if default expiration limit has been reached (24 hours in one of the example provider implementations). **Notification URL and token** Developers have a chance to specify callback URL on which notifications (eg. session termination) regarding the session can be received from the service provider. This is an optional parameter. -Sample API invocations are presented in Section 4.5. +Sample API invocations are presented in Section 4.6. ## 3\. Authentication and Authorization The QoD Service API makes use of the client credentials grant which is applicable for server to server use cases involving trusted partners or clients without any protected user data involved. -In this method the API invoker client is registered as a confidential client with an authorization grant type of client\_credentials [3]. +In this method the API invoker client is registered as a confidential client with an authorization grant type of client_credentials [3]. ## 4\. API Documentation @@ -52,7 +52,7 @@ In this method the API invoker client is registered as a confidential client wit ### 4.2 Details The usage of the QoD API is based on QoS profile classes and parameters which define App-Flows. -Based on the API, QoS sessions can be created, queried, and deleted. Once an offered QoS profile class is requested, application users get a prioritized service with stable latency or throughput even in the case of congestion.The QoD API has the following characteristics: +Based on the API, QoS sessions can be created, queried, and deleted. Once an offered QoS profile class is requested, application users get a prioritized service with stable latency or throughput even in the case of congestion. The QoD API has the following characteristics: * A specified App-Flow is prioritized to ensure stable latency or throughput for that flow * The prioritized App-Flow is described by providing information such as source & destination IP address and port/port-ranges @@ -70,10 +70,10 @@ This sample is taken from the agreed sample (example) set from the Camara-projec | **QoD profile** | **Details** | | ------------------- | ------- | -| QOS_E | Enhanced communication class with with stable latency under congestion (e.g. throughput up-to 2Mbps) | -| QOS_S | Small class of throughput profile - for example DL (Downlink) up-to 10Mbps | -| QOS_M | Medium class of throughput profile - for example DL (Downlink) up-to 30Mbps | -| QOS_L | Large class of throughput profile - for example DL (Downlink) up-to 100Mbps | +| QOS_E | Enhanced communication class where latency stays stable under congestion (throughput upto 500kbps). The application bitrate should not exceed 500kbps. | +| QOS_S | Small class of throughput profile - for example The 5G System throughput is prioritized up to 20Mbps. At high load, the throughput is capped at 20Mbps and can be degraded to lower effective throughput (without a minimum level). | +| QOS_M | Medium class of throughput profile - for example throughput is prioritized up to 8Mbps. At high load, the throughput is capped at 8Mbps and can be degraded to lower effective throughput (without a minimum level). | +| QOS_L | Large class of throughput profile - for example throughput is dprioritized up to 4Mbps. At high load, the throughput is capped at 4Mbps and can be degraded to lower effective throughput (without a minimum level). | ### 4.3 Endpoint Definitions @@ -90,21 +90,21 @@ Following table defines API endpoints of exposed REST based for QoD management o | **Create QoD Session** | | -------------------------- | -| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \
[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**qos:** Qualifier for the requested latency/throughput profile.
LOW\_LATENCY - to request the stable latency
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** | +| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose one of the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [5] assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
**asId:** The identifier used for application server. The developer can choose from one of the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile.
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API.

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** |
#### QoD Query for QoS Session | **Quering QoS Session information** | | --------------------------------------- | -| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePorts (optional):** The requested port(s) on the user equipment which can be either be specified as ranges or .
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested Latency profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since unix epoch.

**401:** Un-authorised, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. | +| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePorts (optional):** The requested port(s) on the user equipment which can be either be specified as ranges or .
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested Latency profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since unix epoch.

**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. |
#### QoD Delete QoS Session | **Deleting QoS session** | | ---------------------------- | -| **HTTP Request**
DELETE\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that need to terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found | +| **HTTP Request**
DELETE\/qod-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that needs to be terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found | ### 4.4 Errors @@ -112,7 +112,7 @@ Since CAMARA QoD API is based on REST design principles and blueprints, well def codes and families specified by community are followed [4]. Details of HTTP based error/exception codes for the QoD API are described in Section 4.2 of each API REST based method. -Following table provides an overview of common error names, codes and messages applicable to QoD API. +Following table provides an overview of common error names, codes, and messages applicable to QoD API. | No | Error Name | Error Code | Error Message | | --- | ---------- | ---------- | ------------- | @@ -122,7 +122,7 @@ Following table provides an overview of common error names, codes and messages a |4 |400 | INVALID_INPUT | "Expected property is missing: uePorts" | |5 |400 | INVALID_INPUT | "Expected property is missing: qos" | |6 |400 | INVALID_INPUT | "Ranges not allowed: uePorts" | -|7 |401 | UNAUTHORIZED | "Authorization to invoke operation" | +|7 |401 | UNAUTHORIZED | "No authorization to invoke operation" | |8 |403 | FORBIDDEN | "Operation not allowed" | |9 |404 | NOT_FOUND | "Session Id does not exist" | |10 |409 | CONFLICT | "Another session is created for the same UE" | @@ -170,3 +170,4 @@ N/A [2] Camara QoS/QCI mapping table https://github.com/camaraproject/QualityOnDemand/blob/main/code/API_definitions/QoSProfile_Mapping_Table.md
[3] Camara Commonalities : Authentication and Authorization Concept for Service APIs https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/Working/CAMARA-AuthN-AuthZ-Concept.md
[4] HTTP Status codes spec https://restfulapi.net/http-status-codes/ +[5] GPSI external identifier https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/UE-Identification.md From 0256d6cd0bf25d034ed0b32fa370d4653860d3df Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Tue, 15 Nov 2022 23:35:19 +0100 Subject: [PATCH 11/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 31 +++++++++++----------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 1139045fe7..c5e3d8abff 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -1,6 +1,6 @@ # Overview -The Quality-On-Demand (QoD) API provides programmable interface for developers and other users (capabilities consumers) to request stable latency or throughput managed by Telco networks without the necessity to have an in-depth knowledge of the 4G/5G system or the overall complexity of the Telecom Systems [1]. +The Quality-On-Demand (QoD) API provides programmable interface for developers and other users (capabilities consumers) to request stable latency or throughput managed by Telco networks without the necessity to have an in-depth knowledge of the 4G/5G system or the overall complexity of the Telecom Systems [[1]](#1). ## 1\. Introduction @@ -41,7 +41,7 @@ Sample API invocations are presented in Section 4.6. The QoD Service API makes use of the client credentials grant which is applicable for server to server use cases involving trusted partners or clients without any protected user data involved. -In this method the API invoker client is registered as a confidential client with an authorization grant type of client_credentials [3]. +In this method the API invoker client is registered as a confidential client with an authorization grant type of client_credentials [[3]](#3). ## 4\. API Documentation @@ -66,7 +66,7 @@ Following diagram shows the interaction between different components QoD_LM The below table shows sample QoS profiles and are subject to service provider customizations. -This sample is taken from the agreed sample (example) set from the Camara-project [2]. +This sample is taken from the agreed sample (example) set from the Camara-project [[2]](#2). | **QoD profile** | **Details** | | ------------------- | ------- | @@ -90,14 +90,14 @@ Following table defines API endpoints of exposed REST based for QoD management o | **Create QoD Session** | | -------------------------- | -| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose one of the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [5] assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
**asId:** The identifier used for application server. The developer can choose from one of the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile.
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events .
  Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API.

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** | +| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose one of the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [[5]](#5) assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
**asId:** The identifier used for application server. The developer can choose from one of the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile. e.g. QOS_E
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events. e.g. '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API. e.g. c8974e592c2fa383d4a3960714

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
e.g. 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
e.g. 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch. e.g. 1639566000

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input.**
**500:** **Session not created.**
**503:** **Service temporarily unavailable.** |
#### QoD Query for QoS Session | **Quering QoS Session information** | | --------------------------------------- | -| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePorts (optional):** The requested port(s) on the user equipment which can be either be specified as ranges or .
**asPort (optional):** The requested port(s) on the user equipment.
**qos:** Qualifier of the requested Latency profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since unix epoch.

**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. | +| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueId:** The identifier of the user equipment.
**asId:** The identifier of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested QoS profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since Unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since Unix epoch.

**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. |
#### QoD Delete QoS Session @@ -108,10 +108,9 @@ Following table defines API endpoints of exposed REST based for QoD management o ### 4.4 Errors -Since CAMARA QoD API is based on REST design principles and blueprints, well defined HTTP status -codes and families specified by community are followed [4]. +Since CAMARA QoD API is based on REST design principles and blueprints, well defined HTTP status codes and families specified by community are followed [[4]](#4). -Details of HTTP based error/exception codes for the QoD API are described in Section 4.2 of each API REST based method. +Details of HTTP based error/exception codes for the QoD API are described in Section 4.3 of each API REST based method. Following table provides an overview of common error names, codes, and messages applicable to QoD API. | No | Error Name | Error Code | Error Message | @@ -137,14 +136,14 @@ N/A
Snippet 1, elaborates REST based API call with "*curl"* to create a QoS session for sample streaming service with following parameters: -* Latency QoS session with QoS-profile "QOS_E" mapping, -* App-Flow is specified for UE-Terminal IP address (ueAddr=10.0.0.1), Application server network (asAddr=54.204.25.0/28) and Port number (asPorts=33001). +* QoS session with QoS-profile "QOS_E" mapping, +* App-Flow is specified for UE-Terminal identifier (ueId=2001:db8:85a3:8d3:1319:8a2e:370:7344), Application server identifier (asAddr=54.204.25.0/28) and Port number (asPorts=33001). Please note, the credentials for API authentication purposes need to be adjusted based on target security system configuration. | Snippet 1. Create QoS session | | ----------------------------------------------- | -| curl -X 'POST' `https://sample-base-url/qod-api/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"ueAddr": "10.0.0.1",
"asAddr": "54.204.25.0/28",
"asPorts": "33001",
"qos": "QOS_E",
"notificationUri": `https://your-callback-server.com/notifications`,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' | +| curl -X 'POST' `https://sample-base-url/qod-api/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"ueId": "2001:db8:85a3:8d3:1319:8a2e:370:7344",
"asId": "54.204.25.0/28",
"asPorts": "33001",
"qos": "QOS_E",
"notificationUri": `https://your-callback-server.com/notifications`,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' |
Snippet 2, elaborates sample QoS notification "SESSION_TERMINATION" message distributed from QoD backend to client callback function. @@ -166,8 +165,8 @@ N/A ## References -[1] 3GPP TS 23.501: System architecture for the 5G System (5GS); Stage 2 (Release 17), V17.4.0 (2022-03)
-[2] Camara QoS/QCI mapping table https://github.com/camaraproject/QualityOnDemand/blob/main/code/API_definitions/QoSProfile_Mapping_Table.md
-[3] Camara Commonalities : Authentication and Authorization Concept for Service APIs https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/Working/CAMARA-AuthN-AuthZ-Concept.md
-[4] HTTP Status codes spec https://restfulapi.net/http-status-codes/ -[5] GPSI external identifier https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/UE-Identification.md +[1] 3GPP TS 23.501: System architecture for the 5G System (5GS); Stage 2 (Release 17), V17.4.0 (2022-03)
+
[2] [Camara QoS/QCI mapping table](https://github.com/camaraproject/QualityOnDemand/blob/main/code/API_definitions/QoSProfile_Mapping_Table.md)
+
[3] [Camara Commonalities : Authentication and Authorization Concept for Service APIs](https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/Working/CAMARA-AuthN-AuthZ-Concept.md)
+
[4] [HTTP Status codes spec](https://restfulapi.net/http-status-codes/)
+
[5] [GPSI external identifier](https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/UE-Identification.md) From 4988cdf0b6ad456eeac5850831fec1c1e95a2da8 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Tue, 15 Nov 2022 23:42:15 +0100 Subject: [PATCH 12/38] Delete QoD_Stable_Bandwidth_API.md --- .../QoD_Stable_Bandwidth_API.md | 161 ------------------ 1 file changed, 161 deletions(-) delete mode 100644 documentation/API_documentation/QoD_Stable_Bandwidth_API.md diff --git a/documentation/API_documentation/QoD_Stable_Bandwidth_API.md b/documentation/API_documentation/QoD_Stable_Bandwidth_API.md deleted file mode 100644 index 4edfe8d098..0000000000 --- a/documentation/API_documentation/QoD_Stable_Bandwidth_API.md +++ /dev/null @@ -1,161 +0,0 @@ -# Overview - -The Quality-On-Demand (QoD) API for stable throughput provides programmable interface for developers and other users (capabilities consumers) to specify stable data-transfer throughput managed by Telco networks, without necessity to have in-depth knowledge of the 4G/5G system complexity by abstracting the internal complexity of telecom systems [1]. - -## 1\. Introduction - -Industrial (IoT), VR/Gaming, broadcasting, autonomous driving and many others scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable bandwidth from the network can improve user experience.. - -The QoD throughput API offers the application developers and users the capability to request for stable throughput for a specified App-Flow between User Equipment (application clients) and Application Services (backend services). The developer has a pre-defined set of QoS_Profiles which he could choose from depending on his throughput requirements. - -QoD_BM - - -## 2\. Quick Start - -The usage of the stable throughput API is based on QoS sessions, which can be created (based on available QoS profiles), queried and deleted. -The deletion of a requested session can be triggered by the user or can be triggered automatically. The automatic process is triggered either when the user specified duration has reached its limit, or default session expiration time has been reached (within reference implementation set to 24hrs). - -Before starting to use the API, the developer needs to know about the below specified details: - -**Base URL** -The RESTful Stable Throughput API endpoint, for example [**https://telekom-api.developer.telekom.com/5g-throughput**](https://telekom-api.developer.telekom.com/5g-throughput) - -**Authentication** -Configure security access keys such as OAuth 2.0 client credentials to be used by Client applications which will invoke the QoD API. - -**QoS Profile** -Define throughput requirements of the application and identify QoS profile class which maps into the required performance category. - -**App-Flow** -Describes the precise flow the developer wants to prioritize and have stable bandwidth for. This flow is described using source and destination IP addresses, ports and protocols with flow direction. - -**Duration** -Define the number of seconds for which the QoD session should be created. This parameter is optional and if not specified, the session is either deleted on user request or if default expiration limit has been reached (24 hours in reference implementation). - -**Notification URL and token** -Developers have a chance to specify callback URL on which notifications (eg. session termination) regarding the session can be received from the service provider. This is also an optional parameter. - -Sample API invocations are presented in Section 4.5. - -## 3\. Authentication and Authorization - -The QoD Service API makes use of the client credentials grant which is applicable for server to server use cases involving trusted partners or clients without any protected user data involved. -In this method the API invoker client is registered as a confidential client with an authorization grant type of client\_credentials [3]. - -## 4\. API Documentation - -### 4.1 Details -The usage of the QoD throughput API is based on QoS profile classes and parameters which define App-Flows. -Based on the API, QoS sessions can be created, queried, and deleted.The QoD bandwidth API has the following characteristics: -* A specified App-Flow is prioritized to ensure stable throughput for that flow -* The prioritized App-Flow is described by providing additional information such as protocols, ports, uplink/downlink direction of flow etc. -* Stable bandwidth is requested by selecting from the list of QoS profiles made available by the service provider (e.g. Small ,Medium, Large) to map throughput requirements -* The developer can optionally specify the duration for which he needs the prioritized App-flow -* The developer can optionally also specify callback URL on which notifications for the session can be sent -
-Following diagram shows the interaction between different components - -
-QoD_BM - -The below table shows sample QoS profiles and are subject to service provider customizations. This sample is taken from the agreed sample (example) set from the Camara-project [2]. - -| **QoD throughput profile** | **Details** | -| ---------------------- | ------- | -| *THROUGHPUT\_S* | Small class of throughput profile - for example DL (Downlink) up-to 10Mbps | -| *THROUGHPUT\_M* | Medium class of throughput profile - for example DL (Downlink) up-to 30Mbps | -| *THROUGHPUT\_L* | Large class of throughput profile - for example DL (Downlink) up-to 100Mbps | - -### 4.2 Endpoint Definitions - -Following table defines API endpoints of exposed REST based for QoD throughput management operations. - -| **Endpoint** | **Operation** | **Description** | -| -------- | --------- | ----------- | -| POST
\/qod-bandwidth-api/v0/sessions | **Create Throughput Session** | Create QoS Session to manage throughput priorities | -| GET
\/qod-bandwidth-api/v0/sessions/{sessionId} | **Query for Throughput** | Querying for QoS throughput session information details | -| DELETE
\/qod-bandwidth-api/v0/sessions/{sessionId} | **Delete Throughput Session** | Deleting a QoS throughput session | -
- -#### QoD Create Throughput QoS Session Operation - -| **Create throughput QoS session** | -| ----------------------------- | -| **HTTP Request**
POST \/qod-bandwidth-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set.
**ueAddr:** The IPv4 address of the user equipment. It can contain a single IP address or a range, using a mask.
Format: \
[/\]
- address : an IPv4 number in dotted-quad form 1.2.3.4. Only this exact IP number will match the flow control rule.
- address/mask : an IP number as above with a mask width of the form 1.2.3.4/24.
*In this case, all IP numbers from 1.2.3.0 to 1.2.3.255 will match. The bit width MUST be valid for the IP version.*
**asAddr:** The IPv4 address of the application server. It can contain a single IP address or a range, using a mask.

**uePort (optional):** A list of single ports or port ranges on the user equipment.
Ports may be specified as <\{port\|port\-port\}\[\,ports\[\,\.\.\.\]\]\>\.
The '-' notation specifies a range of ports (including boundaries).
Example: '5010-5020,5021,5022'
**asPort (optional):** A list of single ports or port ranges on the application server.
**protocolIn:** The used transport protocol for the uplink.
TCP - TCP protocol
UDP - UDP protocol
ANY - all protocols
**protocolOut :** The used transport protocol for the downlink.
TCP - TCP protocol
UDP - UDP protocol
ANY - all protocols
**qos:** Qualifier for the requested throughput profile (QoS values based on example mapping and might differ in production networks).
THROUGHPUT\_S - Example: downlink up to 10Mbps
THROUGHPUT\_M - Example: downlink up to 30Mbps
THROUGHPUT\_L - Example: downlink up to 100Mbps
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events
Example: '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentification token for callback API.
Example: 'c8974e592c2fa383d4a3960714'

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**protocolIn:** The used transport protocol for the uplink.
**protocolOut:** The used transport protocol for the downlink.
**qos:** QoS qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
Example: 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since unix epoch.
Example: 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since unix epoch.

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input**
**500:** **Session not created**
**503:** **Service temporarily unavailable** | -
- -#### QoD Query for Throughput QoS Session - -| **Quering QoS session throughput information** | -| ------------------------------------------ | -| **HTTP Request**
GET\/qod-bandwidth-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**duration:** Session duration in seconds.
**ueAddr:** The ipv4 address of the user equipment.
**asAddr:** The ipv4 address of the application server.
**uePort (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the user equipment.
**protocolIn:** The used transport protocol for the uplink.
**protocolOut:** The used transport protocol for the downlink.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since unix epoch.

**401:** Un-authorised, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. | - -#### QoD Delete Throughput QoS Session - -| **Deleting QoS throughput session** | -| ------------------------------- | -| **HTTP Request**
DELETE\/qod-bandwidth-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that need to terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found | - -### 4.3 Errors - -Since CAMARA QoD API is based on REST design principles and blueprints, well defined HTTP status -codes and families specified by community are followed [4]. - -Details of HTTP based error/exception codes for the QoD API are described in Section 4.2 of each API REST based method. -Following table provides an overview of common error names, codes and messages applicable to QoD API. - -| No | Error Name | Error Code | Error Message | -| --- | ---------- | ---------- | ------------- | -| 1 | Invalid port(s) | 400 | "Ports specification not valid | -| 2 | Invalid protocol | 400 | "Validation failed for parameter: protocol" | -| 3 | Invalid QoS profile | 400 | "Validation failed for parameter: QoS-profile" | -| 4 | Invalid IP address (format) | 400 | "Validation failed for parameter: IP-addr" | -| 5 | Invalid duration | 400 | "Validation failed for parameter: Session duration" | -| 6 | Unauthorized | 401 | "Un-authorized to invoke operation" | -| 7 | Forbidden | 403 | "Forbidden to invoke operation" | -| 8 | Session with same parameters already exists | 409 | "Found session \ already active until \" | -| 9 | Service unavailable | 503 | “Internal error due to requrired telco service unvailability" | - - -### 4.4 Policies - -N/A - -### 4.5 Code Snippets - -Snippet 1, elaborates REST based API call with "*curl"* to create a QoS session for sample streaming service with following parameters: - -* Throughput QoS session with 1H duration and QoS-profile "L" mapping, -* App-Flow is specified for UDP protocol with UE-Terminal IP address (ueAddr=10.0.0.1), Application server network (asAddr=54.204.25.0/28) and Port number (asPorts=33001). - -Please note, the credentials for API authentication purposes need to be adjusted based on target security system configuration. - -| Snippet 1. Create QoS session to manage throughput | -| -------------------------------------------------- | -| curl -X 'POST' `https://sample-base-url/qod-bandwidth-api/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"duration": 3600,
"ueAddr": "10.0.0.1",
"asAddr": "54.204.25.0/28",
"asPorts": "33001",
"protocolOut": "UDP",
"qos": "THROUGHPUT\_L",
"notificationUri": `https://your-callback-server.com/notifications` ,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' | -
-Snippet 2, elaborates sample QoS notification "SESSION_TERMINATION" message distributed from QoD backend to client callback function. - -| Snippet 2. Sample QoS session notification | -| ------------------------------------------ | -| {
   "sessionId": 
"3fa85f64-5717-4562-b3fc-2c963f66afa6"    "event": "SESSION\_TERMINATED"} | - -### 4.6 FAQ's - -(FAQs will be added in a later version of the documentation) - -### 4.7 Terms - -N/A - -### 4.8 Release Notes - -N/A - -## References - -[1] 3GPP TS 23.501: System architecture for the 5G System (5GS); Stage 2 (Release 17), V17.4.0 (2022-03)
-[2] Camara QoS/QCI mapping table https://github.com/camaraproject/QualityOnDemand/blob/main/code/API_definitions/QoSProfile_Mapping_Table.md
-[3] Camara Commonalities : Authentication and Authorization Concept for Service APIs https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/Working/CAMARA-AuthN-AuthZ-Concept.md
-[4] HTTP Status codes spec https://restfulapi.net/http-status-codes From 95df1ae973048b65cc196c8e03e5de2125c6073c Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 17 Nov 2022 16:19:27 +0100 Subject: [PATCH 13/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index c5e3d8abff..8f3db5785e 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -58,7 +58,8 @@ Based on the API, QoS sessions can be created, queried, and deleted. Once an off * The prioritized App-Flow is described by providing information such as source & destination IP address and port/port-ranges * The developer can optionally specify the duration for which they need the prioritized App-flow * Stable latency or throughput is requested by selecting from the list of QoS profiles made available by the service provider (e.g. QOS_E) to map latency requirements -* The developer can optionally also specify callback URL on which notifications for the session can be sent +* The developer can optionally also specify callback URL on which notifications for the session can be sent
+ Following diagram shows the interaction between different components
From 16ee95e1fad82d4bc916a219979213d724012c27 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 17 Nov 2022 18:05:36 +0100 Subject: [PATCH 14/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 8f3db5785e..01d1a29a71 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -91,21 +91,21 @@ Following table defines API endpoints of exposed REST based for QoD management o | **Create QoD Session** | | -------------------------- | -| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose one of the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [[5]](#5) assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
**asId:** The identifier used for application server. The developer can choose from one of the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile. e.g. QOS_E
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events. e.g. '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API. e.g. c8974e592c2fa383d4a3960714

**Response**
**201: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
e.g. 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
e.g. 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch. e.g. 1639566000

**400:** **Invalid input.**
**401:** **Un-authorized, missing or incorrect authentication.**
**405:** **Invalid input.**
**500:** **Session not created.**
**503:** **Service temporarily unavailable.** | +| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose one of the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [[5]](#5) assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
**asId:** The identifier used for application server. The developer can choose from one of the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile. e.g. QOS_E
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events. e.g. '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API. e.g. c8974e592c2fa383d4a3960714

**Response**
**200: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
e.g. 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
e.g. 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch. e.g. 1639566000

**400:** **Invalid input.**
**401:** **Un-authorized.
**403:** Forbidden.**
**409:** **Conflict.**
**500:** **Server Error.**
**503:** **Service temporarily unavailable.** |
#### QoD Query for QoS Session | **Quering QoS Session information** | | --------------------------------------- | -| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueId:** The identifier of the user equipment.
**asId:** The identifier of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested QoS profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since Unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since Unix epoch.

**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found.
**503:** Service temporarily unavailable. | +| **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueId:** The identifier of the user equipment.
**asId:** The identifier of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested QoS profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since Unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since Unix epoch.

**401:** Un-authorized.
**403:** Forbidden.
**404:** Session not found.
**503:** Service temporarily unavailable. |
#### QoD Delete QoS Session | **Deleting QoS session** | | ---------------------------- | -| **HTTP Request**
DELETE\/qod-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that needs to be terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized, missing or incorrect authentication.
**404:** Session not found | +| **HTTP Request**
DELETE\/qod-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that needs to be terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized.
**403:** Forbidden.
**404:** Session not found.
**503:** Service temporarily unavailable.| ### 4.4 Errors @@ -144,7 +144,7 @@ Please note, the credentials for API authentication purposes need to be adjusted | Snippet 1. Create QoS session | | ----------------------------------------------- | -| curl -X 'POST' `https://sample-base-url/qod-api/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"ueId": "2001:db8:85a3:8d3:1319:8a2e:370:7344",
"asId": "54.204.25.0/28",
"asPorts": "33001",
"qos": "QOS_E",
"notificationUri": `https://your-callback-server.com/notifications`,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' | +| curl -X 'POST' `https://sample-base-url/qod-api/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"ueId": {"ipv6Addr": "2001:db8:85a3:8d3:1319:8a2e:370:7344"},
"asId": {"ipv4Addr": "54.204.25.0/28"},
"asPorts": "33001",
"qos": "QOS_E",
"notificationUri": `https://your-callback-server.com/notifications`,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' |
Snippet 2, elaborates sample QoS notification "SESSION_TERMINATION" message distributed from QoD backend to client callback function. From 198aceabc41f638b120ea194b9a6ba313161af45 Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 17 Nov 2022 19:25:49 +0100 Subject: [PATCH 15/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 01d1a29a71..bf31b7b909 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -26,8 +26,14 @@ Security access keys such as OAuth 2.0 client credentials used by Client applica **QoS Profile** Latency or throughput requirements of the application mapped to relevant QoS profile class. +**Identifier for the the user equipment (UE)** +At least one identifier for the user equipment out of four options: IPv4 address, IPv6 address, MSISDN, or external ID [[5]](#5) assigned by the Mobile Operator for the user equipment + +**Identifier for the application server (AS)** +IPv4 and/or IPv6 address of the application server (application backend) + **App-Flow** -The precise IP flow the developer wants to prioritize and have stable latency or throughput for. This flow is described using source and destination IP addresses and ports/port-ranges. +The precise IP flow the developer wants to prioritize and have stable latency or throughput for. This flow is in the current API version determined by the IP addresses of the user equipment and the application server. And can be further described with ports or port-ranges. Future version of the API might allow more detailed flow descriptions. **Duration** Number of seconds for which the QoD session should be created. This parameter is optional and if not specified, the session is either deleted on user request or if default expiration limit has been reached (24 hours in one of the example provider implementations). @@ -55,9 +61,9 @@ The usage of the QoD API is based on QoS profile classes and parameters which de Based on the API, QoS sessions can be created, queried, and deleted. Once an offered QoS profile class is requested, application users get a prioritized service with stable latency or throughput even in the case of congestion. The QoD API has the following characteristics: * A specified App-Flow is prioritized to ensure stable latency or throughput for that flow -* The prioritized App-Flow is described by providing information such as source & destination IP address and port/port-ranges +* The prioritized App-Flow is described by providing information such as user equipment (UE) IP address (or other UE identifier) & application server (AS) IP addresses and port/port-ranges * The developer can optionally specify the duration for which they need the prioritized App-flow -* Stable latency or throughput is requested by selecting from the list of QoS profiles made available by the service provider (e.g. QOS_E) to map latency requirements +* Stable latency or throughput is requested by selecting from the list of QoS profiles made available by the service provider (e.g. QOS_E) to map latency and throughput requirements * The developer can optionally also specify callback URL on which notifications for the session can be sent
Following diagram shows the interaction between different components @@ -66,15 +72,14 @@ Following diagram shows the interaction between different components QoD_LM -The below table shows sample QoS profiles and are subject to service provider customizations. -This sample is taken from the agreed sample (example) set from the Camara-project [[2]](#2). +The below table shows one possible example how QoS profiles are mapped to connectivity characteristics. They are subject to agreements between the communication service provider and the API invoker. This sample is taken from from the reference draft within the CAMARA project [[2]](#2). | **QoD profile** | **Details** | | ------------------- | ------- | | QOS_E | Enhanced communication class where latency stays stable under congestion (throughput upto 500kbps). The application bitrate should not exceed 500kbps. | | QOS_S | Small class of throughput profile - for example The 5G System throughput is prioritized up to 20Mbps. At high load, the throughput is capped at 20Mbps and can be degraded to lower effective throughput (without a minimum level). | | QOS_M | Medium class of throughput profile - for example throughput is prioritized up to 8Mbps. At high load, the throughput is capped at 8Mbps and can be degraded to lower effective throughput (without a minimum level). | -| QOS_L | Large class of throughput profile - for example throughput is dprioritized up to 4Mbps. At high load, the throughput is capped at 4Mbps and can be degraded to lower effective throughput (without a minimum level). | +| QOS_L | Large class of throughput profile - for example throughput is prioritized up to 4Mbps. At high load, the throughput is capped at 4Mbps and can be degraded to lower effective throughput (without a minimum level). | ### 4.3 Endpoint Definitions @@ -91,7 +96,7 @@ Following table defines API endpoints of exposed REST based for QoD management o | **Create QoD Session** | | -------------------------- | -| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose one of the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [[5]](#5) assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
**asId:** The identifier used for application server. The developer can choose from one of the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile. e.g. QOS_E
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events. e.g. '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API. e.g. c8974e592c2fa383d4a3960714

**Response**
**200: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
e.g. 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
e.g. 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch. e.g. 1639566000

**400:** **Invalid input.**
**401:** **Un-authorized.
**403:** Forbidden.**
**409:** **Conflict.**
**500:** **Server Error.**
**503:** **Service temporarily unavailable.** | +| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose to provide the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [[5]](#5) assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
NOTE: the communication service provider (CSP) might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different CSPs. In this case the identifiers MUST belong to the same UE
**asId:** The identifier used for application server. The developer can choose from the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile. e.g. QOS_E
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events. e.g. '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API. e.g. c8974e592c2fa383d4a3960714

**Response**
**200: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
e.g. 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
e.g. 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch. e.g. 1639566000

**400:** **Invalid input.**
**401:** **Un-authorized.
**403:** Forbidden.**
**409:** **Conflict.**
**500:** **Server Error.**
**503:** **Service temporarily unavailable.** |
#### QoD Query for QoS Session From f2141e90203beb0a54dff2ddc1dedbbe3e864676 Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 17 Nov 2022 19:29:32 +0100 Subject: [PATCH 16/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index bf31b7b909..4d7bbbe7ab 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -172,7 +172,7 @@ N/A ## References
[1] 3GPP TS 23.501: System architecture for the 5G System (5GS); Stage 2 (Release 17), V17.4.0 (2022-03)
-
[2] [Camara QoS/QCI mapping table](https://github.com/camaraproject/QualityOnDemand/blob/main/code/API_definitions/QoSProfile_Mapping_Table.md)
-
[3] [Camara Commonalities : Authentication and Authorization Concept for Service APIs](https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/Working/CAMARA-AuthN-AuthZ-Concept.md)
+
[2] [CAMARA QoS Profiles Mapping Table (REFERENCE DRAFT)](https://github.com/camaraproject/QualityOnDemand/blob/main/code/API_definitions/QoSProfile_Mapping_Table.md)
+
[3] [CAMARA Commonalities : Authentication and Authorization Concept for Service APIs](https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/Working/CAMARA-AuthN-AuthZ-Concept.md)
[4] [HTTP Status codes spec](https://restfulapi.net/http-status-codes/)
[5] [GPSI external identifier](https://github.com/camaraproject/WorkingGroups/blob/main/Commonalities/documentation/UE-Identification.md) From 5c84946415cf281a2c43cc4e9f2774a81a7ecee5 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 17 Nov 2022 20:05:19 +0100 Subject: [PATCH 17/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 4d7bbbe7ab..93f0d1437a 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -143,7 +143,7 @@ N/A Snippet 1, elaborates REST based API call with "*curl"* to create a QoS session for sample streaming service with following parameters: * QoS session with QoS-profile "QOS_E" mapping, -* App-Flow is specified for UE-Terminal identifier (ueId=2001:db8:85a3:8d3:1319:8a2e:370:7344), Application server identifier (asAddr=54.204.25.0/28) and Port number (asPorts=33001). +* App-Flow is specified for UE-Terminal identifier (ueId=2001:db8:85a3:8d3:1319:8a2e:370:7344), Application server identifier (asId=54.204.25.0/28) and Port number (asPorts=33001). Please note, the credentials for API authentication purposes need to be adjusted based on target security system configuration. From b4a294f8d9baf7729a9a1186e8324d2ae73229cc Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 17 Nov 2022 20:09:12 +0100 Subject: [PATCH 18/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 93f0d1437a..65d6a8e8f9 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -33,7 +33,7 @@ At least one identifier for the user equipment out of four options: IPv4 address IPv4 and/or IPv6 address of the application server (application backend) **App-Flow** -The precise IP flow the developer wants to prioritize and have stable latency or throughput for. This flow is in the current API version determined by the IP addresses of the user equipment and the application server. And can be further described with ports or port-ranges. Future version of the API might allow more detailed flow descriptions. +The precise IP flow the developer wants to prioritize and have stable latency or throughput for. This flow is in the current API version determined by the identifiers used for the user equipment and the application server. And can be further elaborated with details such as ports or port-ranges. Future version of the API might allow more detailed flow descriptions. **Duration** Number of seconds for which the QoD session should be created. This parameter is optional and if not specified, the session is either deleted on user request or if default expiration limit has been reached (24 hours in one of the example provider implementations). From 7cae218752f6ba114c89e23ef04eb83713d614ea Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 17 Nov 2022 20:10:38 +0100 Subject: [PATCH 19/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 65d6a8e8f9..081d73ca56 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -60,11 +60,11 @@ In this method the API invoker client is registered as a confidential client wit The usage of the QoD API is based on QoS profile classes and parameters which define App-Flows. Based on the API, QoS sessions can be created, queried, and deleted. Once an offered QoS profile class is requested, application users get a prioritized service with stable latency or throughput even in the case of congestion. The QoD API has the following characteristics: -* A specified App-Flow is prioritized to ensure stable latency or throughput for that flow -* The prioritized App-Flow is described by providing information such as user equipment (UE) IP address (or other UE identifier) & application server (AS) IP addresses and port/port-ranges -* The developer can optionally specify the duration for which they need the prioritized App-flow -* Stable latency or throughput is requested by selecting from the list of QoS profiles made available by the service provider (e.g. QOS_E) to map latency and throughput requirements -* The developer can optionally also specify callback URL on which notifications for the session can be sent
+* A specified App-Flow is prioritized to ensure stable latency or throughput for that flow. +* The prioritized App-Flow is described by providing information such as user equipment (UE) IP address (or other UE identifier) & application server (AS) IP addresses and port/port-ranges. +* The developer can optionally specify the duration for which they need the prioritized App-flow. +* Stable latency or throughput is requested by selecting from the list of QoS profiles made available by the service provider (e.g. QOS_E) to map latency and throughput requirements. +* The developer can optionally also specify callback URL on which notifications for the session can be sent.
Following diagram shows the interaction between different components From 9434d647f3a8b67010c7d29a160833019208e14e Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Fri, 18 Nov 2022 13:35:08 +0100 Subject: [PATCH 20/38] Update QoD_API.md --- documentation/API_documentation/QoD_API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 081d73ca56..cfeb12cbe1 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -77,9 +77,9 @@ The below table shows one possible example how QoS profiles are mapped to connec | **QoD profile** | **Details** | | ------------------- | ------- | | QOS_E | Enhanced communication class where latency stays stable under congestion (throughput upto 500kbps). The application bitrate should not exceed 500kbps. | -| QOS_S | Small class of throughput profile - for example The 5G System throughput is prioritized up to 20Mbps. At high load, the throughput is capped at 20Mbps and can be degraded to lower effective throughput (without a minimum level). | +| QOS_L | Large class of throughput profile - for example The 5G System throughput is prioritized up to 20Mbps. At high load, the throughput is capped at 20Mbps and can be degraded to lower effective throughput (without a minimum level). | | QOS_M | Medium class of throughput profile - for example throughput is prioritized up to 8Mbps. At high load, the throughput is capped at 8Mbps and can be degraded to lower effective throughput (without a minimum level). | -| QOS_L | Large class of throughput profile - for example throughput is prioritized up to 4Mbps. At high load, the throughput is capped at 4Mbps and can be degraded to lower effective throughput (without a minimum level). | +| QOS_S | Small class of throughput profile - for example throughput is prioritized up to 4Mbps. At high load, the throughput is capped at 4Mbps and can be degraded to lower effective throughput (without a minimum level). | ### 4.3 Endpoint Definitions From 68c1c6245058cbc7dd34064d2f41f54410c08830 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Mon, 21 Nov 2022 16:45:10 +0100 Subject: [PATCH 21/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: tlohmar --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index cfeb12cbe1..80e4a9f2d1 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -6,7 +6,7 @@ Industrial (IoT), VR/Gaming, broadcasting, autonomous driving and many others scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable latency (reduced jitter) or stable throughput from the network can improve user experience substantially. -The QoD API offers the application developers the capability to request for stable latency (reduced jitter) or throughput for a specified App-Flow between User Equipment (application clients) and Application Servers (backend services). The developer has a pre-defined set of Quality of Service (QoS) Profiles which they could choose from depending on their latency or throughput requirements. +The QoD API offers the application developers the capability to request for stable latency (reduced jitter) or throughput for some specified application data flows between application clients (within a User Equipment) and Application Servers (backend services). The developer has a pre-defined set of Quality of Service (QoS) Profiles which they could choose from depending on their latency or throughput requirements. QoD_LM From ece82ef9b5e5a1348278f268df0269f3bb5b8fb9 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Mon, 21 Nov 2022 18:29:20 +0100 Subject: [PATCH 22/38] Update QoD_API.md to fix https://github.com/camaraproject/QualityOnDemand/pull/71#discussion_r1026430503 --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 80e4a9f2d1..fa5c9aac48 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -4,7 +4,7 @@ ## 1\. Introduction -Industrial (IoT), VR/Gaming, broadcasting, autonomous driving and many others scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable latency (reduced jitter) or stable throughput from the network can improve user experience substantially. +Industrial (IoT), VR/Gaming, live video streaming, autonomous driving and many other scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable latency (reduced jitter) or stable throughput from the network can improve user experience substantially. The QoD API offers the application developers the capability to request for stable latency (reduced jitter) or throughput for some specified application data flows between application clients (within a User Equipment) and Application Servers (backend services). The developer has a pre-defined set of Quality of Service (QoS) Profiles which they could choose from depending on their latency or throughput requirements. From 5439ec096d0e5f2b6de96b7b70924299de1b82cc Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 1 Dec 2022 11:38:04 +0100 Subject: [PATCH 23/38] changed qod-api to qod changed urls which included qod-api to qod to comply with api spec 0.8.0 --- documentation/API_documentation/QoD_API.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index fa5c9aac48..555dbc17bf 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -87,16 +87,16 @@ Following table defines API endpoints of exposed REST based for QoD management o | **Endpoint** | **Operation** | **Description** | | -------- | --------- | ----------- | -| POST
\/qod-api/v0/sessions | **Create QoD Session** | Create QoS Session to manage latency/throughput priorities | -| GET
\/qod-api/v0/sessions/{sessionId} | **Query for QoD Session** | Querying for QoD session information details | -| DELETE
\/qod-api/v0/sessions/{sessionId} | **Delete QoD Session** | Deleting a QoD session | +| POST
\/qod/v0/sessions | **Create QoD Session** | Create QoS Session to manage latency/throughput priorities | +| GET
\/qod/v0/sessions/{sessionId} | **Query for QoD Session** | Querying for QoD session information details | +| DELETE
\/qod/v0/sessions/{sessionId} | **Delete QoD Session** | Deleting a QoD session |
#### QoD Create QoS Session Operation | **Create QoD Session** | | -------------------------- | -| **HTTP Request**
POST \/qod-api/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose to provide the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [[5]](#5) assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
NOTE: the communication service provider (CSP) might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different CSPs. In this case the identifiers MUST belong to the same UE
**asId:** The identifier used for application server. The developer can choose from the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile. e.g. QOS_E
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events. e.g. '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API. e.g. c8974e592c2fa383d4a3960714

**Response**
**200: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
e.g. 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
e.g. 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch. e.g. 1639566000

**400:** **Invalid input.**
**401:** **Un-authorized.
**403:** Forbidden.**
**409:** **Conflict.**
**500:** **Server Error.**
**503:** **Service temporarily unavailable.** | +| **HTTP Request**
POST \/qod/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose to provide the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [[5]](#5) assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
NOTE: the communication service provider (CSP) might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different CSPs. In this case the identifiers MUST belong to the same UE
**asId:** The identifier used for application server. The developer can choose from the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile. e.g. QOS_E
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events. e.g. '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API. e.g. c8974e592c2fa383d4a3960714

**Response**
**200: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
e.g. 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
e.g. 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch. e.g. 1639566000

**400:** **Invalid input.**
**401:** **Un-authorized.
**403:** Forbidden.**
**409:** **Conflict.**
**500:** **Server Error.**
**503:** **Service temporarily unavailable.** |
#### QoD Query for QoS Session @@ -110,7 +110,7 @@ Following table defines API endpoints of exposed REST based for QoD management o | **Deleting QoS session** | | ---------------------------- | -| **HTTP Request**
DELETE\/qod-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that needs to be terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized.
**403:** Forbidden.
**404:** Session not found.
**503:** Service temporarily unavailable.| +| **HTTP Request**
DELETE\/qod/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that needs to be terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized.
**403:** Forbidden.
**404:** Session not found.
**503:** Service temporarily unavailable.| ### 4.4 Errors @@ -149,7 +149,7 @@ Please note, the credentials for API authentication purposes need to be adjusted | Snippet 1. Create QoS session | | ----------------------------------------------- | -| curl -X 'POST' `https://sample-base-url/qod-api/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"ueId": {"ipv6Addr": "2001:db8:85a3:8d3:1319:8a2e:370:7344"},
"asId": {"ipv4Addr": "54.204.25.0/28"},
"asPorts": "33001",
"qos": "QOS_E",
"notificationUri": `https://your-callback-server.com/notifications`,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' | +| curl -X 'POST' `https://sample-base-url/qod/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"ueId": {"ipv6Addr": "2001:db8:85a3:8d3:1319:8a2e:370:7344"},
"asId": {"ipv4Addr": "54.204.25.0/28"},
"asPorts": "33001",
"qos": "QOS_E",
"notificationUri": `https://your-callback-server.com/notifications`,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' |
Snippet 2, elaborates sample QoS notification "SESSION_TERMINATION" message distributed from QoD backend to client callback function. From fa840e7767b0150a022433dff147b8b4bcf62e07 Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 1 Dec 2022 17:06:04 +0100 Subject: [PATCH 24/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: tlohmar --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 555dbc17bf..93ea23b684 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -17,7 +17,7 @@ The deletion of a requested session can be triggered by the user or can be trigg Before starting to use the API, the developer needs to know about the below specified details: -**Base-URL** +**QOD service endpoint** The RESTful QoD API endpoint **Authentication** From 1327c73452bdfca97fd1f9786032a4bce09bfa40 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 1 Dec 2022 17:07:43 +0100 Subject: [PATCH 25/38] update qos-session to qos-session-resource to fix https://github.com/camaraproject/QualityOnDemand/pull/71#discussion_r1026439102 --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 93ea23b684..f489d7a263 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -12,7 +12,7 @@ The QoD API offers the application developers the capability to request for stab ## 2\. Quick Start -The usage of the API is based on QoS sessions, which can be created (based on available QoS profiles), queried and deleted. +The usage of the API is based on QoS session resource, which can be created (based on available QoS profiles), queried and deleted. The deletion of a requested session can be triggered by the user or can be triggered automatically. The automatic process is triggered either when the user specified duration of a QoS session has reached its limit or the default session expiration time has been reached (within an example provider implementation it is set to 24hrs). Before starting to use the API, the developer needs to know about the below specified details: From 11cf10a90ef12dd12973b43187e935c3b082fd35 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 1 Dec 2022 17:11:29 +0100 Subject: [PATCH 26/38] update qod-session to qod-session resource to fix https://github.com/camaraproject/QualityOnDemand/pull/71#discussion_r1026439102 --- documentation/API_documentation/QoD_API.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index f489d7a263..1e4356e081 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -92,23 +92,23 @@ Following table defines API endpoints of exposed REST based for QoD management o | DELETE
\/qod/v0/sessions/{sessionId} | **Delete QoD Session** | Deleting a QoD session |
-#### QoD Create QoS Session Operation +#### QoD Create QoS Session Resource Operations -| **Create QoD Session** | +| **Create QoD Session Resource** | | -------------------------- | | **HTTP Request**
POST \/qod/v0/sessions
**Query Parameters**
No query parameters are defined.
**Path Parameters**
No path parameters are defined.
**Request Body Parameters**
**duration (optional)**: Session duration in seconds. Maximal value of 24 hours is used if not set. e.g. 86400
**ueId:** The identifier for the user equipment(device). The developer can choose to provide the below specified user equipment identifiers:
- IPv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
- msisdn (including country code and optionally could be prefixed by "+" sign) e.g. 004912345678923
- externalId [[5]](#5) assigned by the Mobile network Operator for the user equipment. e.g. 123456789@domain.com
NOTE: the communication service provider (CSP) might support only a subset of these options. The API invoker can provide multiple identifiers to be compatible across different CSPs. In this case the identifiers MUST belong to the same UE
**asId:** The identifier used for application server. The developer can choose from the below application server identifiers:
- ipv4 address (supports mask) e.g. 192.168.0.1/24
- ipv6 address (supports mask) e.g. 2001:db8:85a3:8d3:1319:8a2e:370:7344
**uePorts (optional):** A list of single ports or port ranges on the user equipment.
e.g. "uePorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**asPorts (optional):** A list of single ports or port ranges on the application server. e.g. "asPorts": {"ranges": [{"from": 5010,"to": 5020}],"ports": [5060,5070]}
**qos:** Qualifier for the requested latency/throughput profile. e.g. QOS_E
**notificationUri (optional):** URI of the callback receiver. Allows asynchronous delivery of session related events. e.g. '[https://application-server.com/notifications](https://application-server.com/notifications)'
**notificationAuthToken (optional):** Authentication token for callback API. e.g. c8974e592c2fa383d4a3960714

**Response**
**200: Session created**
Response body:
**duration:** Session duration in seconds.
**ueId:** The identifier of the user equipment
**asId:** The identifer of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPorts (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested throughput profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
e.g. 123e4567-e89b-12d3-a456-426614174000
**startedAt:** Timestamp of session start, in seconds since Unix epoch.
e.g. 1639479600
**expiresAt**: Timestamp of session expiration if the session was not deleted, in seconds since Unix epoch. e.g. 1639566000

**400:** **Invalid input.**
**401:** **Un-authorized.
**403:** Forbidden.**
**409:** **Conflict.**
**500:** **Server Error.**
**503:** **Service temporarily unavailable.** |
-#### QoD Query for QoS Session +#### QoD Query for QoS Session Resource -| **Quering QoS Session information** | +| **Quering QoS Session Resource information** | | --------------------------------------- | | **HTTP Request**
GET\/qod-latency-api/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session id that was obtained from the Create QoS Session operation.
**Request Body Parameters**
No request body parameters are defined.
**Response**

**200: Session information returned.**
Response body:
**ueId:** The identifier of the user equipment.
**asId:** The identifier of the application server.
**uePorts (optional):** The requested port(s) on the user equipment.
**asPort (optional):** The requested port(s) on the application server.
**qos:** Qualifier of the requested QoS profile.
**notificationUri (optional):** URI of the callback receiver.
**notificationAuthToken (optional):** Authentication token for callback API.
**id:** Session ID in UUID format.
**startedAt:** Timestamp of session start in seconds since Unix epoch.
**expiresAt:** Timestamp of session expiration if the session was not deleted in seconds since Unix epoch.

**401:** Un-authorized.
**403:** Forbidden.
**404:** Session not found.
**503:** Service temporarily unavailable. |
-#### QoD Delete QoS Session +#### QoD Delete QoS Session Resource -| **Deleting QoS session** | +| **Deleting QoS session resource** | | ---------------------------- | | **HTTP Request**
DELETE\/qod/v0/sessions/{sessionId}
**Query Parameters**
No query parameters are defined.
**Path Parameters**
sessionId: Session ID that needs to be terminated.
**Request Body Parameters**
No request body parameters are defined.

**Response**
**204:** Session deleted
**401:** Un-authorized.
**403:** Forbidden.
**404:** Session not found.
**503:** Service temporarily unavailable.| @@ -147,7 +147,7 @@ N/A Please note, the credentials for API authentication purposes need to be adjusted based on target security system configuration. -| Snippet 1. Create QoS session | +| Snippet 1. Create QoS session resource | | ----------------------------------------------- | | curl -X 'POST' `https://sample-base-url/qod/v0/sessions`
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...."
-d '{
"ueId": {"ipv6Addr": "2001:db8:85a3:8d3:1319:8a2e:370:7344"},
"asId": {"ipv4Addr": "54.204.25.0/28"},
"asPorts": "33001",
"qos": "QOS_E",
"notificationUri": `https://your-callback-server.com/notifications`,
"notificationAuthToken": "c8974e592c2fa383d4a3960714"
}' |
From 422c3f55e573377ca9b538d8bc8e8b9c133591c8 Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 1 Dec 2022 17:25:31 +0100 Subject: [PATCH 27/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: Jose Luis Urien --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 1e4356e081..e43486c87d 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -13,7 +13,7 @@ The QoD API offers the application developers the capability to request for stab ## 2\. Quick Start The usage of the API is based on QoS session resource, which can be created (based on available QoS profiles), queried and deleted. -The deletion of a requested session can be triggered by the user or can be triggered automatically. The automatic process is triggered either when the user specified duration of a QoS session has reached its limit or the default session expiration time has been reached (within an example provider implementation it is set to 24hrs). +The deletion of a requested session can be triggered by the API consumer or can be triggered automatically. The automatic process is triggered either when the requested specified duration of a QoS session has reached its limit or the default session expiration time has been reached (within an example provider implementation it is set to 24hrs). Before starting to use the API, the developer needs to know about the below specified details: From c4865a1e05ffb8bd8ecffd79a8b26d577e6a0a68 Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 1 Dec 2022 17:31:50 +0100 Subject: [PATCH 28/38] removed mapping table and just kept the link --- documentation/API_documentation/QoD_API.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index e43486c87d..15d792d12d 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -72,14 +72,8 @@ Following diagram shows the interaction between different components QoD_LM -The below table shows one possible example how QoS profiles are mapped to connectivity characteristics. They are subject to agreements between the communication service provider and the API invoker. This sample is taken from from the reference draft within the CAMARA project [[2]](#2). - -| **QoD profile** | **Details** | -| ------------------- | ------- | -| QOS_E | Enhanced communication class where latency stays stable under congestion (throughput upto 500kbps). The application bitrate should not exceed 500kbps. | -| QOS_L | Large class of throughput profile - for example The 5G System throughput is prioritized up to 20Mbps. At high load, the throughput is capped at 20Mbps and can be degraded to lower effective throughput (without a minimum level). | -| QOS_M | Medium class of throughput profile - for example throughput is prioritized up to 8Mbps. At high load, the throughput is capped at 8Mbps and can be degraded to lower effective throughput (without a minimum level). | -| QOS_S | Small class of throughput profile - for example throughput is prioritized up to 4Mbps. At high load, the throughput is capped at 4Mbps and can be degraded to lower effective throughput (without a minimum level). | +How QoS profiles are mapped to connectivity characteristics are subject to agreements between the communication service provider and the API invoker. Within the CAMARA project, you can find a sample for such a mapping of QoS profiles. [[2]](#2) + ### 4.3 Endpoint Definitions From 7f2ac6f1e8a8f4eb302b315a0d225833def28f3b Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 1 Dec 2022 17:50:31 +0100 Subject: [PATCH 29/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: tlohmar --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 15d792d12d..ec2aa8216e 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -33,7 +33,7 @@ At least one identifier for the user equipment out of four options: IPv4 address IPv4 and/or IPv6 address of the application server (application backend) **App-Flow** -The precise IP flow the developer wants to prioritize and have stable latency or throughput for. This flow is in the current API version determined by the identifiers used for the user equipment and the application server. And can be further elaborated with details such as ports or port-ranges. Future version of the API might allow more detailed flow descriptions. +The precise application data flow the developer wants to prioritize and have stable latency or throughput for. This flow is in the current API version determined by the identifiers used for the user equipment and the application server. And can be further elaborated with details such as ports or port-ranges. Future version of the API might allow more detailed flow identification features. **Duration** Number of seconds for which the QoD session should be created. This parameter is optional and if not specified, the session is either deleted on user request or if default expiration limit has been reached (24 hours in one of the example provider implementations). From 4a49703849168ab40bfbeffda0ef5e3767cf67fe Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 1 Dec 2022 17:55:35 +0100 Subject: [PATCH 30/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: tlohmar --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index ec2aa8216e..a0b2a3c4bc 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -18,7 +18,7 @@ The deletion of a requested session can be triggered by the API consumer or can Before starting to use the API, the developer needs to know about the below specified details: **QOD service endpoint** -The RESTful QoD API endpoint +The URL pointing to the RESTful resource of the QoS API. **Authentication** Security access keys such as OAuth 2.0 client credentials used by Client applications to invoke the QoD API. From fe0f0223200584ea8166009b3d298c1187674044 Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 1 Dec 2022 18:14:13 +0100 Subject: [PATCH 31/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: tlohmar --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index a0b2a3c4bc..0e5d7b2c01 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -32,7 +32,7 @@ At least one identifier for the user equipment out of four options: IPv4 address **Identifier for the application server (AS)** IPv4 and/or IPv6 address of the application server (application backend) -**App-Flow** +**Application data flow (between the application client and application server)** The precise application data flow the developer wants to prioritize and have stable latency or throughput for. This flow is in the current API version determined by the identifiers used for the user equipment and the application server. And can be further elaborated with details such as ports or port-ranges. Future version of the API might allow more detailed flow identification features. **Duration** From f3f2cf02585233e3bfb39a2700276fb784a665a6 Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 1 Dec 2022 18:15:30 +0100 Subject: [PATCH 32/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: tlohmar --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 0e5d7b2c01..6a77989d37 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -36,7 +36,7 @@ IPv4 and/or IPv6 address of the application server (application backend) The precise application data flow the developer wants to prioritize and have stable latency or throughput for. This flow is in the current API version determined by the identifiers used for the user equipment and the application server. And can be further elaborated with details such as ports or port-ranges. Future version of the API might allow more detailed flow identification features. **Duration** -Number of seconds for which the QoD session should be created. This parameter is optional and if not specified, the session is either deleted on user request or if default expiration limit has been reached (24 hours in one of the example provider implementations). +Duration (in seconds) for which the QoD session (between application client and application server) should be created. This parameter is optional. When not specified, a default session duration (e.g. 24 hours) is applied. The user may request a termination before its expiration. **Notification URL and token** Developers have a chance to specify callback URL on which notifications (eg. session termination) regarding the session can be received from the service provider. This is an optional parameter. From d90c1f6e5ec2508f6e2b9531531ae5a6afb137e6 Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 1 Dec 2022 18:15:50 +0100 Subject: [PATCH 33/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: tlohmar --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 6a77989d37..25619f0b5a 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -39,7 +39,7 @@ The precise application data flow the developer wants to prioritize and have sta Duration (in seconds) for which the QoD session (between application client and application server) should be created. This parameter is optional. When not specified, a default session duration (e.g. 24 hours) is applied. The user may request a termination before its expiration. **Notification URL and token** -Developers have a chance to specify callback URL on which notifications (eg. session termination) regarding the session can be received from the service provider. This is an optional parameter. +Developers may provide a callback URL on which notifications (eg. session termination) regarding the session can be received from the service provider. This is an optional parameter. Sample API invocations are presented in Section 4.6. From d3d72f45eb76e37033925bceaa44ef9f27cbfba3 Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 1 Dec 2022 18:16:07 +0100 Subject: [PATCH 34/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: tlohmar --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 25619f0b5a..560cb8c374 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -45,7 +45,7 @@ Sample API invocations are presented in Section 4.6. ## 3\. Authentication and Authorization -The QoD Service API makes use of the client credentials grant which is applicable for server to server use cases involving trusted partners +The QoD Service API makes use of the OAUTH 2.0 client credentials grant which is applicable for server to server use cases involving trusted partners or clients without any protected user data involved. In this method the API invoker client is registered as a confidential client with an authorization grant type of client_credentials [[3]](#3). From 64861cf878997ea4cf2dde84a680d41f8bc9dabc Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Thu, 1 Dec 2022 18:23:07 +0100 Subject: [PATCH 35/38] Update QoD_API.md Further minor changes --- documentation/API_documentation/QoD_API.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 560cb8c374..823793078d 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -12,7 +12,7 @@ The QoD API offers the application developers the capability to request for stab ## 2\. Quick Start -The usage of the API is based on QoS session resource, which can be created (based on available QoS profiles), queried and deleted. +The usage of the API is based on QoS session resources, which can be created (based on available QoS profiles), queried and deleted. The deletion of a requested session can be triggered by the API consumer or can be triggered automatically. The automatic process is triggered either when the requested specified duration of a QoS session has reached its limit or the default session expiration time has been reached (within an example provider implementation it is set to 24hrs). Before starting to use the API, the developer needs to know about the below specified details: @@ -32,7 +32,7 @@ At least one identifier for the user equipment out of four options: IPv4 address **Identifier for the application server (AS)** IPv4 and/or IPv6 address of the application server (application backend) -**Application data flow (between the application client and application server)** +**App-Flow (between the application client and application server)** The precise application data flow the developer wants to prioritize and have stable latency or throughput for. This flow is in the current API version determined by the identifiers used for the user equipment and the application server. And can be further elaborated with details such as ports or port-ranges. Future version of the API might allow more detailed flow identification features. **Duration** @@ -58,7 +58,7 @@ In this method the API invoker client is registered as a confidential client wit ### 4.2 Details The usage of the QoD API is based on QoS profile classes and parameters which define App-Flows. -Based on the API, QoS sessions can be created, queried, and deleted. Once an offered QoS profile class is requested, application users get a prioritized service with stable latency or throughput even in the case of congestion. The QoD API has the following characteristics: +Based on the API, QoS session resources can be created, queried, and deleted. Once an offered QoS profile class is requested, application users get a prioritized service with stable latency or throughput even in the case of congestion. The QoD API has the following characteristics: * A specified App-Flow is prioritized to ensure stable latency or throughput for that flow. * The prioritized App-Flow is described by providing information such as user equipment (UE) IP address (or other UE identifier) & application server (AS) IP addresses and port/port-ranges. From 2d31e824f28a9b6c4392aa7a816231623189799e Mon Sep 17 00:00:00 2001 From: Shilpa Padgaonkar <77152136+shilpa-padgaonkar@users.noreply.github.com> Date: Thu, 1 Dec 2022 20:27:11 +0100 Subject: [PATCH 36/38] updated callflow pic to fix https://github.com/camaraproject/QualityOnDemand/pull/71/files#r1026484537 --- .../resources/QoD_details.PNG | Bin 28084 -> 82804 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/documentation/API_documentation/resources/QoD_details.PNG b/documentation/API_documentation/resources/QoD_details.PNG index 0547d67fc2658a60c935f5d9af2718765770c750..a6a7e1db9f798e2dbf48a9c7e86670413f1db857 100644 GIT binary patch literal 82804 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ȌvbV6Nd z@^H^+u{Px7Y8f5?((vyCPvZ_!65m0r*@{c)=QPTbW}oXAk(d?OV3ne#>CjMT4UiQ`^LB$LnjM^Pb<8uyg|o2Uf_nFs%iOnef4EAtVd(VHOg^H2hu8J*#ru^sj}`rZ(e4%`kYCW zoET}7+=wXUZ@QhhJt*xQe~W88=WUui;)a!}Iw|q+ti+Vv_%N}m(oAdd?!7@M(Z8F$ z>ypj)oMN2ySlMgougAB+fB*AZXBxQ~s2y8~S>hSo zwXBP68?3w6r!0VbeOy_Srz+L3`TIJ2+{ zl=ChHg=gq&>|X0Yfy$xU`wpK~_Q|gRB#w!orHt!7j+U@#abuh6?v^TNUbz0O<-N{1 ztkX!HZ}Gf&#rDK@WbhA{FVWos!jsCaa&EB;{qd&hIWiX1242$Cmvkd1L3;aX_GR)< zv3mn83RC3sxKO8>OZP6weOgs9M0|X$=^waaxkB#tS;-p!Br=~X(1WjV8DF@vw6Qzn zWT0!~{v(`*QW3qcI=0GFO4!O`r>-MVFkn?2dL(y%Eqg>@5_dz&#==5n_mV)WqnNPEjx6`XO+7#IqD|VUKg48lQ;AjOf9D z7gyIwv;qG+ib83=z@NZY3L(_RGa|cndurv{g@j{5p-pt@ zV4Qw4rnJOHUOQ&w{m74zlp)A8^VobCY={wWa>Jhwo6w$_CH&zR>U?i{d|Wz<$H2{` zxqkO-ae#QYjC=e0fyQk2AFMp2M4VmWyB{om1?X>DO+PS(e`PVCC9# zQ+nyjjVH<&4i6??6_K==?(MAnj(f$mUFUsmJ=}`F`b%Q*GlGx%gLm?^Z_cxtLrqw$ zr{n+y6=ExvVVTPo7N%;LF&A3byLPsusy6BE0`o}6)BD1FIS(4u`eaH@ zquYO>cW_1!kJM$Zm`xQNQpna|Es7Z;fIm%g2a63p5jX`q&hY@Oxsxj3)~ck zPe>B#(WKExd`qUsikzMQx~!;!4Vv5huCNtt*Q>9ehlb0a>GRzweGzk^MRY9nOqbWJ z3hU+euWJH38Y4Z+1&cGMJa=FD+oo_erONWf$i$^pGHwkRs*~7f6ll2Z4v4m8f+Wuy zi%n=CFL`mL^58Q~{Dre|yBcom8rzS_79lQfr!#7^?t^vHhM2>Mn`mjo0vcfx*hNK4 zcvme)yo$8X$$u(Nn=k~#sjXDGVj=V(v0lLCHBGV-w@o{@Fhcih&!?mv&SPRd{f3~4 zENzz0X@{_DYK);oJWZoC_RooauUxxB)zb4LtzAtUk7@C(MC(`;Lwfu~28(m=xj1&3 znp;^Sb>+uBIW2Y8ANrF{K3gNO*uFT1#>1l`u}_gY@e9A9u1@!MSJAJT2AdmG=Y_|I zm#+@;M6&|W$E{P-^4s#HuXo5MHbJ`A;bYS=vv;gUo~fjC1cTR(UzH5IoK?!@e>QIR zVVx46KcTV<8J56=f*V`fRWSR#HHSlVRVdW=^)+F;=*!z0UYYy8BQI!foI(e&+Kfah zY(#Q%UsGau z3(ha(9JY&ZlJojcCi}Dvf0W8|w-nXS>g5!MtQ4;7dPyksddk3+EPjKUNdfbisNL>u z;~@O&PiE{k1IO(gko7CIE@5LLnrog|q(M63jinnrIX6oY9T>L1@ zLKFGZb5RxcHzxJop~0_UwJK3-WAvu3K$c`!(qlBK5P>b81lcu$jNE=LPYatX-MXeP zS9be7EvgxemoDu@daUvrg-ZOmpDytc#b6($U;PptdfTr(M2XLB=^9|`Z_5NiUlG4C zSUIlEE-8tA5IE{=A50Ba;7@xC+1|8wKfBn;QJiKv*>7)A$7)rt=ny5o%fuBIU_UfI z6x7~L=VzD$Pf}9;Ii@d;W1u_H692$aEs2Om}0m)C*pz z=FGr?I#F+Gx_!&e(eQr-%r!vxw5sURkm>hldnGl zb0YvPvAg7UxOlj)(~aBzmC>Ft_)x-0GIr{BDMg8pD3hXWdgsqqxVBqK%w69v7}@_K ziiCaR7HKpKJuPJ*SD^AT`2*1sk?4BW`dJASIcHruvS5fNKjq=|xj;pv?3%?yuP4*% zpzZRS_5VZ5xJs}~p9vzHUo46c#avs4`fTN&>7 zq%dRSaz-zo$Y+Z)J^2Xz@hsIh`vszxp&fqyiE=h~IZ_U1cvGYMo}EJLNl=g7W(!Si zlqQoev&v*_dr0Ozqmb?-EqkePN4BBg#yC5k@Ey<)>e2nflcq!-ff|U&qilOC3l@`M&)+B9?_C@^S4t zc1-HwU1^C20!(9`?bel7vuw3RH?QT)XS9br``hANav$ix+=dx^9_OF*Afd5gtP=;!Kp=3umY(zgVEqwib zc8o3iz|-VNag{mk%wLAf&%??hBhKMJxyzcnqnmbapx39^Kvg{jZgssn#U}3A@~0WM zZaiL{8V-VcQ%!v~#*q*InfKy#v(PM*gpp3Mj(XdA#Ymj!w@3ucV-Jo+%HzL>S);$Z zH^@#=-LSVSNP_2DkvFc+{kXbpvJ^`d$ItJjDD>x7OV>>em5P?Ht=61seJ3lrrkQ@&nr8d!7)mn_Shjk|)#l_Lf{AvjUEsEO zPCN(8nP7i@$t_Yv+=F7s#i{-Xy&LU~`nP(^{Myh5`@T$4miSB>NAk!Qa zixVx z_PPR>f4FqfVS&UZ?eettb)$&0l+-~)29&Qy_qy4RE9lNN-*aUh*}2kq_7k(^z6D=@ z-S$i^xY{i~23c>npW|~9VGVQX{bYgVZC2wsm>n=tB34raG$nQ!^6!aXLqb&3>#Lo2 zORL>C^ewU|J0D#{(RaHcF8b=I3Eu17qW<+mq-(e3LCHrjPTY^Flj;|b} zJKh{|R|JS$B?J;At4mzpYje7<*NqOvXam^-;?gqoWr#N$DV35~hbBE7cA~aFvcr$!9eImU#m6!ON1hx8f-#wy)5_2Fn?DI-qU$4g(oc{Vb~4 z9(T1#iUL2YGHp@NtJ*`CXG;Pl@hDXF*@@bm$go_BDFS+jkjmF3>bCa!$@U>6#G&ymMy6R`-SiSmz!6FgloH@xIZ$Dfrt~=`Xz!sR#ig?*e}>{0rP`pB_Iagq$H0#s%*XI*GNq5yCOmw}z!I4$9I= z+9{SfzW>kV47N>|17}t0LKHYbj1r11PP5eO z#65!iXti!NmguIw^Gun=-YJ9_UF|%|E?Y4%o+fwn1rL|{eKs3*at#Ky&gF{%kPj6O z_z$55ig%>)mQ??4*qn7)$@yE(VUqbnPkg+dak~2Vvxc`9wpTlWkpR%Y6PYFYZz04b z(1NGP0l{X$a8K)R5oVe057`t(g9!i64*{%y#KZf)dui!bJJRnIzRsn7ZMt(+R&=HV zIoFLECoeX|$cGVs$U}&taSae)gc_-{3<%qJpd%tD0h**2R-xl>LF3P5#K-Eq#Dt=@%N{o@2DqKvc7@&{8^HJ{@HH@|N3ym>F=mC6k8rE^+h2< z{qLC|&iSM?5|yK+6MtEuvE}waXUqN1eO<2h(Pcnbh!WOYQ2Xu#AeClOisbbTc;kOY z1}Nr(Xs~>?MbN+1EnWPw3M@3=aI(2}= z@0~efP=x{h=a@4>JGEH-c+KG6B(L`gX4wFFaH`WV$K4u!d=(24(kR5|@^Qqgs^*0P z?~?oq;C+bQMI5v`0AwE6?t@B56vB_gAjmqROZ0OgC6f7{#|0RP{_T7(cO7vEdkpCq z-_Ki=ED zK(~i@UAF3P8#MvB?ZYagZu9b(RDQsP>#X#qdt1xK@Lfv4(o_UJ; zC=59(W_=;PBv~c@Y^I}vt92h>YbP}Hn2xK%C!QygJ3zR!9%K-7FqYFU z%K$x_p<^YBichc zjT3MQj=W@LfJbzIK&-c33`M}aBi8!5Bwrm_A8I<+q4IO|oK>&(MugYM#GUpK4`e6F zs606UPsk0D8P7|v)?i{A2AX%9_EE=at}xyo&sxox(61bMl70$Z874B$O+Ppe{Jm?F zqw}l_*GJ-Mvd)YgLi>~-Q4C7?q{K`Sclc5ES3hQ7+3*x?OFB6#MIstp&J>{1^m$NZ zt8sQ8Sd~wQvlQiAa6>jrrTT*Bk5Bh>K*b0*e%Hw65NILeqaTlv>dt(jQ4;jIv48JM zq5f_uO8qdEc{)+PDVAega0V^<&@syqLpuqkmGVeOib>0V#-ATF8GK-FNx&8MZX)$d zY^cBKs8%z(|DG`Px)*t(64oju++mT>Ht%R8zQWNM6ccjVykmJx^W5aYda31J*bB-= zsT4n%I8*w0g*#`Q97+%TICAe$#%YpH zmBGQ{>UjBYWSr6=MI*56ie%(8Tr`IM<=+QeRzlA*-I-hBZKMgR75)XS7xMwF9?$k> zYW2A+H?)Cqo8W)uzzImMq8n}(8^t|E6M^S3k5zye`?B|uR{ zAcmR5?&csk6L%nHix_B&FVS-i+v($P$!rA8~ae=y~mJ6#p~>E7As%Vf4l0$97tJ#PZYTjh})z@jjE|r^d57(^uaBGe$=EShnLozYx zuziik#)&kB^2tkQ$VbZj=NvTapQO^S*D*^5lkc)T9YuKG?g}@@zvCIlFug(DuL+37 zv`VjmEEG5WDCHDd+ju!TdWkL8fh|OX=CVZn>vlBs0mv&d=dOmVo`nWG`jsCcGlsUQ#|zrMoAGo~VKLL2(sfjy*p z2w)v1^3WzvCiUPbtm@_CPsSr@oDlkF9IctpQ}<<k26`2z@Rm}I6a#UrzSMQ%8Au3T% zq)~1~%Dla%=(2P*dqD;At_ahNw=1C&7l9sa^5`jhpflP!=rcLNa1laW+}K&^_(avC zBi5ndh(b@^lTT|jDNd8bS{^8!rL;^n9mSQ1nSt*U8TL!>w;%@FOf%>M^JP^pQF=izku5ujA8H&pxHmT<;rK2&+u`>vN_gmxd0hVua{l=hZ^OYoiqr65f z%rBC1z>4u*Wjd((#dkLPwlzQ3Nm92NEyE5XZ%7rif_I?V<~Aj z9-`5DnDzNgRKy{BkkBO~2Rny54qyDRkx4i{qcvCRvp&vNZIZ01#_eD1>m39Yt|E>X zt)zrZpT6#}g%!XY9kzWq@vMNY4x)ca?!b%>h!_a~RSzsr&m@%L*k^Wct1V9L=e z83>chU6;{lrsEWWgWTwX!DqrcQpWp(+Eonx=i={^c*ZLu+w9O* z{XLs_UF+!|0^)6D+!CO_>T}fzp04;WKUPH4r>&@yCDJ_{!tN*d_YL>@| z!e_`H>!E$s^jgIN+8S=f;c<@JSPC1ib4F#a#)g!KAvY^ZG zn}=-Qda1+f@*D+!xSBv-4UOEl&i671-OS6@`lJNX+qn`5uH~ zQSZ+4Uh7J^VPi5<-Q4_I<8j1gtQT>dJf_q&lh<+zvW5YNgPERnhP7@MiTPK;<00DT zN?1<>B&E+hM5j2BdCDrRU+NBX=ys|&-cY?jsCwi|?R5t|G&R)G#zX%dhp@h?63~On6VfKaePwslYN#b12(`9#i z!Y0jA%|TG&X-pcuBRNcs&!sZc?`K%N?3ipFZH2uhbX=3J2#-6p``8H`^!G5zB2UsS zjYrLCgQxWBVI>1SiN6?cvHik9usnND&^X1)D*OS8Cd>J7ng-z{(=P# zW*)CY-i$8Go&IuPs$uqk{OPpY~!_J)^>WE<4Yj5LiNp9alxp>6rZ_w$Ve8H^Q`JEv;h zLoPWc>}awhMABu3z}FhUb9DJff|4Q~^4?$4mq~KiW%|=jE6A6RDEovO;(6|&-d}y9 zgz*XSX>k4{>y-H=n0Ly(LMDQpRtq6nK1Qi7y-eYWhb8>lC~e>1gOMk4^tYFzO>)-p zEld4R!eGSK^Y(4t--DlsI{dzj@I)0vNT=gP>N2_iIbZD;1Dyl5@kGH$U+s)OJH5Iw@Hvt^|4KCm%}Mg?o-zK z(#4limU+9_Bz92Kr8*$^i;Gg3?0>0SL525u10)(sNZ-CAMiG*WF92mTQl@?9%q}=S zg@6%`9|pF{XCyU{cZ4Ci3kHOZvVyk(+B)|C63gnG9DwkLV^Y|lDY)z`($d*LLT+y6 zfxQLdf_}rKEBS^wE`JRY^aNnDi9|Whq!d^F9?ob+c&t;x{|!h063C)F1Vm6w$6dBW zUkWx`G2NR0ncM(&9tJvd+q`C3`i(R=oksL%gF4V;g*|E-8Jfd?b%r9OPv2!Bd#D~r zBX7Qq<(i*mcsdL{I_@IVdSgtz6POJP0O7vvVU0E5~M8@A|(iK_##MHGGsRaUr<7f!VV(Z5kH+gwlKl- z@zhyDh_GkJ51B756nYrMiU|YmSxJyo*)&Y8klT}HaLI&i-V*dUGYQ>WrdBTIB9m!~ z9hpo^1x1L!7ZkT2ju?Ht=Lk70uz1EoAuGSU5E5dgO*MNXVt<4A^~f+0+=?nPDq4=@ zPDF?xDmr^)`jq>DWW=nWh67n9(v=>eymr7Y9X0xV5jb?MH-?E36`E@p*YWhgV}T0@ z8*QkLbW;ks3mqEzHM%SSQLF$}k#9W?;yz+}*R3b6chb4cT^Wrg$D55vXR5Rv`Lf`o zW5KO1J-7RhhXPs78y6Nq_gG=ib45RA{{oB}SEt|qyYJDzMG?4XtyZJ7dq6mQwbJr^ z($`j2xO6HJ&Gr_UJHg7HTzGYtyETkr7!X{$28s-6Iyb4Rwxc zJqVc;Pam;U!vR&P14-2Bpw*ZCbxF7yKeE39DG{#&n7xRaTL)=-n+Wh?X|pArGDQ+R z8+PLwF9Dp=Hil-a@<<-w%Iw}I<*1upq6FW;vlb`i+))1SoPv;jJ8}C+NoF6D@lZ4F zq}UJk4fTg77Lg_z5r|oJ3z9%>0DQ8it@YLB==qhR{vVK8!f%vMTZlhqaQ)^W;<}WP zU32PDKUYp2xiRF7a?Koh@;I0>tFrVh8%atr(X|(So?4pQ!x?q}SJ7G<%+@U&K^10d z?o6A}+OW84GFqrNI;6+!;%Y_%q7CgFl>mnV6}EaA(X-S!t*a*SB%J)L7wa1|#wQvZ z(mdbzV@uCb~_f;T>k@m$aMcZeYvw z^A8Es)0e!N#h+ESaxclBP~6Yo$=1~@ee5jt{;izl-MyZz!k#Cm4aciHXRD^hLa#E=fK)d~`BfsW%m-h6YQ`@OmM zN|0=(YT`)7gh;+O@E5_TYTJXXt`AU+U@1mK$R=`Zn+XRDw)eIGsO*j3IN?uR?Se>^ zsk1=CG8N8U^xIvLnzllTXc6dz7Y;Y6Bf!j0?9enuFAoUalOny4!M3*Lj4y)1+AJU| z9Z{!M7YnjYPS6lvYyIdiq#Li;rI4dSKcl#xt)inhYzxbsR^Ut!${-K%jLB-g;Pb|x z#1d&l*gFAgb47&T|J91Pehaa$yP03->1n?aQVbq=e28k#f%M#)+}bn32?*Q05j`7* zH0j9)hqgpy4eonOE6lHC0?0_EnZB|Jppd!#{JJln<^c?AK+UK@;KYw>2Oi+Z+Y8~m z`nf*5?v^475l3oL(^5cA`}Hs@*7uf6f7!UPG$mee4J4?MSe1^Kw#(7*f zUaKi7vMH^Ox>Ujx}z~xiS-#%(zH-ERZqay$Myh3T`L61=&E^*_#j8nHo zfet_JI`zD!Fm|wDR}YcE6^Zw=ne_|!k4ixtCV+ZOBTy6&6#H}f!W~pCBDztX<0|O7 zUmVo^k(^h^Z1=(?OtO%?$E%?PGG3iVf`Q&G7Y4Inb4VWTbb3i026~r%5qbI_cXKt% zuYZ+o#SMQ9O*S@E{`mS{Oq~BTOY3hWCg_c&2a~nQ%AAq!V|}JOO9n=x2BA*EnU1FG&dUs6jnPbSJCCmJ%wVaoowX%&)K2oJV|N zBlx>goW!5UoE(6)YViFw?et2scM@39@=yJKd%aZ=f*&jM$HFhxyRnHs;}0wJudQv1 zoc2pmjgbQs|0>$5Uai1^&}|sXcuGl;FC5Juw}+51XWnI&9gH0PBsE7M;S^6|zrQZf z0bO{s`gDlYrbyvlm`}Y>K;&zkK&zf83UFb<7`E7pi!RrVtu573bb8Yt=zqGoDj-3) zSb1mwN{TGFF0%FIn$wmE!?jt8i{%3G*qRY+rK_mu%C{g|;+@2R4Ye4%CCYw}nG!C} z@E~aABjepu&Izzg{?=zL()=q6`w(*C;w&2yAYiNfnnjh`&X^&{Dj&6DvIAwFh|$#s zI1L?VtH&j~3*H^F^!r@<%YlbFq+KiC;(JP;_-2(rS4Y_ad&Lm1#HXK$R%YhJp zCw*xXKb*uld+54uHM;EuuJv1IB@xooh&SF-gSu{YzA?AmTRsXQ)-vrMTQLPLw|R;H ztrt(cqN*)F+Ax3}f4t$_4prL8PPCnUg3nPSuKNP%sP@&XW&UB z@Cb!UzV1=9!Oe*AW`zSJ1;GKa5CZe`AWPIdycq|{oo+jV+n6Cx z{RWHYLi;7p1=8V}G}$lUWE#((p=Nw8Zuc8=P$%qH(T9h9LkEU9m(6nF1^>;-Y*T(6 z*X=BDjI>pPK8#l8jy#KhzsJIw>iR?l)SqijJ9peASTJnz_Clb=_b)KcK5TP4ASp23 zufNL{^&W~yK93cJrdx0>pQ_1ZX~Gmm*XMBgaaGoBsg_kWcudU+pP$6u8*WHK`EGpxWCC5l-;`Y?R!RBGq zpxa?u{~>iLq((iMz2&4Ypp|2BGkD(_Z&6ung)^SSm;^xWF*Pr69OX3eQD<`W*StV@ z(b$Ky4%o&uB7RX4U5#_vUoZRu0?s&oVy>lOZ+g{;UpgE)bsuPn=a%}jFBXrynKjuo zCfFRS!DPKbOAy+e0YSUBuznNmIPC+r zNIES~1jNA&SY^89I``B{MB6WI%+HW%50ZnN=0%t9(D^O8`3bpI>&*qf)2l;C>^s@F80*++h8e$)zTfjazyF@=am_V<825c&=Dt7g&wF_-cI25T)I=3$ zb;ShZ5?dpv)g;0>ben-lw2RYSusBhAVp};)r0*c9Nb702G3jU;fL>z znG2F=#ygHK2*B|a4H(qK)Tj!_L^j!wy}UDic+Ry=%n`-)5mI2umWGT5thTq1f$p`O_Y2pk+6|H>Nifk9>B9&X>Y}UbFl+4 zF6W3Cnr%wDx%9Y)O}Zvw$rx9JQ=v8{duCUIDSUQnL?SO|izO^GZ zm=k2ZB7ilpqz=cq=HzcYP(s^{d_%Vrxwsx%5hT0fOx z?lfYIQXJdbrP>Vo_LD|yCO||=LoVcZ&02M(x>c`Ws#X!ZW1Zf_r+M8`LOy-03&Cgf zJ7*kyh=Y$0WL#r=$cuXs{l)@NQ+4tIO;z-n+g5DD7H9!s_bes+`{^fXM9^FMC~sRQ z2eXBlmj^ zh{JG>=v41$;>`EWby8~cj9y0MdO<`Gaewy1)?AXX-&F&_yC(C28_mKm9JsCno~sk6 zUva%c0c}E0PrY$t_ig9{l?Zlc;vkwsw8$HjMPogH+dJeXOPN1wQR9l*R7AyK)EQ-E ztF_FtP1=9FpD_XdzOfqLK2W7zQu-*^J7BpQy)(Y|H)d$GdEsz^s&*MNdtP=r>(%Zh4|K-bYoI*AdhuAO|RBW@vrAIsYg5;}JRASL_DZhWF1Fr64 zx{-Hstf}k7pbkkq3KWE56|n# z@_`h$+;nP2RA4HgHz#7eA<7d0$5%kz9J4dBIyw5e@mj7r&cAAxWr|44CALicHC&+V z!hYa`Yc^x?D+n7F@x{6?2OBOTe~Kc5xAz)GZ+SNV)k5`&iiz7 z?Ak`xE_e6jLyxi}PLXOB)CkKa1^a!V2OX<%Ng&)r zk1wVQG(pKc8ZNY9fO}F$8_O41^jLO~2}>S&0I#L(G=G%Tytj%~rekXS9EE=-4cYzTyJa9JR(dr^ zUYetr#MTCwUB|9+p5e5(s^2)$Vx)g~LuFXvf^ zoF!+8$$&1?%5^Jwk5|h->?q@lMQr+5p$M_)YIK0DD-__SqXijOO2zW9_y$uzO8&Oh;l^|gtnRWL=*AhO z%o{}+YLMVV4yI)9V(26yXMFnA5Djb=(V?8gT6;~#!vgy=hxV*025mYd{rQ4gngz9X zC#fST5-ryn%wd;b?zH>PmAaWa(JyP}hVASOqy!)vL8>(3rRqqc^5K^l@v5@a@QPZ{ zv1S79kN`FRXP43w<2)&xO!cqn+>+jJ6HO;%KbxG>YucvQRMQ@H#4R4Lf#BIVj^+jd z8&>U#8N8QgdH=w7WUc+V(utQd8OxD>LWj;dfs7ZuaqIbC^Xe<4?r#Zc2Mz$1?sWXE zTV9&1b8t0fF=zK>WTdJ}L;pEzdS$HB43|?90l#peb;2z#+G4%W)DmaHYyS>rpD0`M zpC_)|tu4r5=%EI8s3Vgxp90=C)b@#qtct}XW8gc>d0&lrwXLp(D*tqru|q6|3qVPv z1ObhV%wEj%sSvr>*a`Np_k87oDN(2zGY_*yHfA4DeKKIzcLFtKu;QNZW@@-8sVmet zJMez!U^#t;d0d0&vZXQ_Y?-YXf4_2l^!qZ4^{Fy1R?Ud6JA$Q>HVPy{%N!H&}`@jU!_@7jr#k`SXYk6|YU?CLCY>pe^k?{O!$AgTSh8 zz+qIWP(EQZQi2l0tSE1e2ks21lUYYW7)doTvu#unwe1za>wZf7WTd)KClK5RwmyAa z3?CHhmoQlNV+!O%*wxM(Z}aZH{G0U~@U@6l&5Vmr&Mh&zD+G+!e~wbhKlXgqxl(U{ zA|RYbF2VFBTjVr?Ch3DH zoOrmZ-hYHqcMcOhXCCMit9)HP4;j0L$RXWDPkKy$j-|)>m~x%s3}GqaKH+e?@?#7D zE*c;IjH#JzrV6#NRMZ0XtDe|OPbvNo>_1fT<4Ta)z{%p;iYcL+vMWt3%0je|8+(D-XYGW z6Tz_CRUaC04omYd=#i|)X0i$08`ptm_u&o>Rwkt0*KX&Zcwxo_feu!k#{60MF4g`@ z6p=Zo>(9$*PNFD@5I4ahI>qLgB#ctoyDSFl_uKZbyXVlWSJ6hE_Jj@w$5c6)&r zX+RD?{{uImRA82J+!$4uF4z{ou0e@raczCR!OJV+TUB;9S3J|&cx2G8cC&(7(_mdJ z29vH?dxKd0WtoJeZ*%qlfX&PW@~j&7=i5JlJ!H(8S``Q2Tg@+8wdWMXnvI*2 z@-cU|!qiNNpq5(9IOsw5oKGm;ksUNgzma)YW70@K_fqgxK_NATzSn+30_ahJuU)PG(qi+saC&0N0 z9`n!CLcW2C8~tTIaI((^MDN_EATMe}Y;tA&nHBb{uY-RCukRY8_j&#z46ddpljEz* zPEDZFzzuG-bUA8@OS@@jj*i}z!7kZC#hD_aB{=nfO=Y5Ocy)dXc4x*ShffXx;)cnk zH+np!`@k0R^+R&K#H5g+37)r(Uq|b6Bk#!1l1j%&cijL9oGJ+D3U?%^uAL1zKLP|l zF`t8t){r_#^i}>d6d{Cj8&PHSVXz15(EO?28MTYYeBD|{U|d(Gv66j`UFXZGsgX#9 zMAg726g(TTV@A(!2G2+^-TlU#+Lqg)CFo;EI#-MI^*HNeVYzklt zdRyx7o4<==g#oi%^bN@nVBFp2eES25SRC&|p2( zQK$dT`v<4REO-dh5Y~9j&cc$-Prl+XK1;W-(fAz2kO~>Dt2Wltt5j}+-Nh3ab?Vd3 z)dWCg^l@*n=xDdM$xMJ^&-r8|uq0eqx2mVU(Xc>n-`r$38*_CU#xs}Yz$+M2 z@UBp?h^%Mi#B4~Z1#0&a?2CMo*5J0(p5nBql8~;V+>uZDSHg$fxCtQlh3yOw#9IOZ zt-t8(UM}vefRGuvUE=ZZwi_M-@y&ZX&N8O?+Q!Rx*p$0yICMikv_>8}pF>{stYe2U z?Ambx+h42L39Ot;v@DtV zun!__EGIhDs{r7yP9BzE2DEK_@`>@I-)u!9x#r@hpBBFut@H$6U}vHciadEv*6t}f zeoQfn3KaxWJVqpHTOj3w>wFy<-fs|p+|&DJ>d{Cob*_$n+Ja<|&itc26)UE|Vzkt8 z>CAYJ>Dbqjt2W-E*Y67SwS}@f2V;&*oI$z)9dOAYCA@=h(1E2V@|}PM>l%d(gx4#c z@Rp<>XOFqD0#Q^|*}{jX4O+7B8-H;-#F+y!uA}ANviAe6FST(3=ui=chE3y)k~(xS z@|v&Fh0+^b5}3RDaC?n}h{Mt6?Z+TNFHKwW7#R3VE<{RJtAtHTL_Yi-iO#cP9<&fBUS;eFCxRgE>2uP0_Y}-ZV_5-!DZ@T``P`r!8SJIoKhhkH zGpFsdjJXyH#@6$;+~t_G?V8K8c^{UrBtnU(FhQ1h*Q)T3$4#m|F%^e}Yt>2g2VYNk ze@^C&lQk(@4Sgz!{x_i44DHfMf-67YV)pEP=XDNS)pH@^C#{i~z@Adhl&d0UA?DrJ z#?b~J&2C;t%F&@`m%>3`b$yhtM>-hi^)Zhl{TeL9YRL4;N1j{5q?amzh}}Xyxu$vh z1@>IvFoEf^Zemv0;i>(e@bwny*oq>Fo8WTa9vDI1FPao_>KnhngM*w3_kw_!W7%(bK`h+3$G_>CTPfR?dOHvN2e4g ztK_fLe|2PyN5a!|qHh`$GHH}G$4C~}?HQ|h06H|MvNJ_EVr??~2h`5=dn2ewVw^0d zUjcw?yN! zdY>gso3%LC1K^eW_C*q#Lls$zfE_Rap9vXQcFo2(p`PN)xZ#2U%gfJC?jE(xi}^LD zcyJNslQsO>H_ao&Wu67}PXebW%LROgaho@6ZxmCfQKqWNtAhZ=m%3;!G#nPC>D);< z0Fs{W0BI7Hsk zZgp@X`Bd%q`*!E6L!K`@)+4l@Q?usUlN#|`c;(p9iF9<8I@IClZ&(VgYtEt#Rqe>>6Y6vrXf;f zG~q=uaci)Y^lBr~RDsCYj;JZQHIikK!bT>vD18c+`V=r7CF3JQh%EJ{!LNdZN?_vX{MV=$+AfrR`)(%os-d(rG~lB1Ps(xI=dR6Pxnc6I%oh zz9x8l`AcIh<9UlvgGf|sGM$(f$#QebYak`~edPk62VMGEiO5I_Gj(cKmc6rfnK}5Z?d*QC zcey0>W!MS)>HdG9;i{L7;@GhI$IQP+sg*)EC18R^tNYGtCl zE?j9$=n|~!w+V#%a~Pa0c!J8s&Wi5kaSPu7fD(oMbD9vB&;aSrH0F+4 z%zXyHB(8^$vSF+vpzj{A;zv4Pr*bp*TBp7AxwU-x3?AaM zxJk|YHmk7)9FqXKDYX}}ibw`6E%E|rT2p$Is%ORngzv|Q6XS*Za$DtC=CJ4G5R-OR z{*)^6vymqNM%Zp>pr^k(y7_>?bl|4Fjo;8Hh74*65sqf)HmMQW7g&8yqrU0F~Uf@B{ z3pyKMe){_r^y*L_i4j5pz1kSSiab=>JbVR(f_m;IoeJhcj~jvBM@CnqdI3QKs^nX5W9C!!FML+rBt#J4x_jGvK z#R@}Jw6e@p787Bt;*^-fkLGKG4IVDZ2ivWaeD9*(B? z7x(4jW#l?{efO@TVan*vHhQ)1%y&}N!7Zn%?JBDD%Zx-B6+1Ud=Zt>!Cc|u|Yv(2` zONkeI5=qqZmG<|v?2f*b=Q=F zOZ|zX4UQ|SgE_KsY~BH8{6ywr6`{J%t%6JYGlV(3;PK4!IfeBHTeBGpMML|K)oKZN zLh?8BU!4{m^`!}|Y2gV8YxK`;dw?j1t%G}T-=*{1vQ zZ@b*odiQG&_u*JV>N#684Fb&58>PSEQ+RCI57x)&f@9Hdlm1vKolBDLh~W#Gnf&yE zZup^X@tLZSi_5!FCnMw0_ZmexW2L%PN+;^Y+MM0NF=r^huPil(W{Dp2%kRa^OG=z1 zr>jM!&yb@#nsJ?v)Vz4PzyD-ZkB&vX;BKCB#wIvKY12imAkS@D)8+HeqXrJ1BJYVyiJV$}CfEnjU^5VK zfUSckCZhme09%d|ycvTwpbhL!QO_V1eZkXh1omgS$^L4a z&y5OSCx2J`O7=J3v_C$Z&aI%fs7I%N+7WSWp8d0bXY8iz0!+|m%GGZ5+u_{l)+J3h zI#|^9oR;5^is@ z`LH(qy$zY*^cyPivbC8^(&&MW^uPfvk^7Pb{;JHtQ~*Y{sQ5w0)F=;@stl zN+!WjV+VtH`q_q1EwBFm%h3|kPx<}@n;teJ`5v1qthG*c(w>NJlDRK|hHZ^ro$V>M zjSp5wFM|h#OH|^sTczUr(@u3DK8MphBAzEJT8RgziWeKhOBeF}^BZ$#$A%H7Zdt;( zU2Dz0Y9^ag?J!aQOM(Zwl?fbiwLac=`@;|x8B}*%rbi@+IK1PkPgaX0TZ3Fe+QVm+ z5r);Ta;>Tdi&zXBVXi*|eL}&?ZY`&4>W;I38?-Ja8m50L-87YRdE~Te<#xNCPxHOH zWc~hkzZ|ay#15k6pf`Cd>{TKP&s(CSzC&|JAE$%z#kGhWN8xS#5(FHR`T#+}y3 zG$@5mW`}}2rwSZD3n%f~1r?}d#TLsS3A`9ek##;gou(nIRyqsF=*}ZNNUr%AMDg)) zTgd!LG-VCb{E90MG12038UCVit5gWL^(NOuOq54a{`fa@p%Rhv=QH)6DW^HdMTyAq z)H9}+)<*9z)y?iGF6clTH!5or5#$_7sYjY%VF=Ip<5t3XSj{`jD9QED+9#=OjKc3& zx5;xvI(x<##xZ2Qq+YwhJ)GC!m-NoXY06?uRAZ?Y!~inZ zp%Nv~Z{G9${;`Oo%LYG_SGp%c$8OrGT_RgbF?ML8a$|YjRF|Ffm)_@>*}d~U9Q|R` zLYu@cv(p0I($?s2l%U>6KU)xi=#!=OTsnd$%W<;KllC8XIIZWiICLuF&mxU(k8X^W zD~FX;WLs%{n4qUIyS*#4H!u$~Z1RnoR=07Vn6%}H!@dEh-Y56L55`!#5IyYt`k+d^ zdhbi+^mDZwL~o`|4aL2^=EA9l7s+7!MzV%xBAni4TT0rDm5a6+_o&G=DL0eM#zpj6o5D`%`ZXL+Qnj{o9I-BBS98Upva9E zc=N`H#kr^d#PyWZ4%-FWPbkdD1T5sm0Of^a>vJlm_u@p_1 zS!Fvd2S*!1LF#LAy-jF>3H^~xff+_wbu`?LH&7UG7To$b>3OJGV zWBdx1j=+F0O4dGZE`@-7Y3=)UN3l&QeyP_@tAw%xMzQw{rLx>!*^oB;x=y|8XRC-o z3=?9m8~Wo~C1)y)-3l2HEu6_Ls9}X!Wa>992zR7!BrXE`>2jd4CR;~K%JBF{;ahAs zznD->cQ#nVcN-2N4^JlZkh66xrf&<6eL*^+2-bpav$nBSMV8(OPYDdzk-(~zFbd9wdu_Tnnj{~;l?2&7xf5lEi1AN? z?+!m~XB%<5R`9&yA6e;38IT(L4Tui-K|;e+QR`PfZqj_aGe$Wpu`WT@o6)51ogY-? z`udhrz3~d9+DIYC(BbQ6`*rGF*G*-gfn^xVfQKj~skswV#JuXo?H}`jo55Sp1_w-6 zgc%Ui84^G9e&|AbpUhd~j0VFCPphlSG4YBHAG-KrUY@Ldq^z41R(Se;5tcts{WJBU z@Z4glOfZuvDc0eXnQpm>|JgdqBrnO;3EEt1{an;fdAIiE6W-?QY`vo<@6oXFG(*-- zQ{Z3Igl9?!Gu{wk?vsUr)1qQDS|Vgl=V#dwzNMy&9T!==nfP+rb*CL#u{mEl`8H}v zMHE0F3g}JJH21mCeDib7ebWAxpRG$Dk0!pEqXl`qVazMsRzN#d{T`d%V5WidRXTj>ip0$!N? zb%69pK#G*nh`$!}YOtq0B(qy-J&Q>iLz3^BWO5D`2>oW#@vTdDvO0PXqZ8l((C*@eC0Ga=eKu)wZ9L{}Fy3 z`#}{X4{R5@2Cs0e!N+F}uP*6c#wP!`M#Hs0W(O*UKLGfi6~MEi zchnNoRh|N0I_SKQ1xJ~&5*zI3mQ+x`;Awg!mpkN_b>PzdfzdSdZzRRFmC{Hg4 zo;Rs~kBdBfEzz_6ldi2;=VQfG93}qZSr{=Air6dVB){oq}Rssl-3H zPVx4J-Y4-dU-&^#tRCpO2MQ|MfS7Opxn5v`CcfE-}>J&>fBH?Vq>c1%vkWfkyp8|HG5tg`*P2qJT$ZSzEZDNxO5@AN+EC*7yd z?|u%o0VOdh#FH0PHzqkRhVzIP3!t!w>z8Y#P2in)bOX1-?Axxsc}xV_ckQY;vdUyy zLb*C9w@SRjYu<3KJ}lSvYgY5@LX zC?O+%g2_;htW<_0ENYQh8Qs85%C7iKWX#@_FQ23o5n;-g$f~83KHTVa8sVHa-x(c# zaef*OK)8;cT{|(tw#oavt=zOT;=(&sz(r|qbwqy3aafV7l)|)yA_^U_Y;57g-P6k*1Ou3 zKl@6)Gwm|l-4sGcn?&I&%|7?M?oqCL%P}t+3cuI<#MdH1;f!*yax|#PHtjCp}hy~f5qxon7=htf!O+HOW z$4eRQy0#7X&(X2T7sjUD+;f$a9*TCL<5IIV9{-|nqiowjsXknptSa4eJKd-T9s@*fnc<;!_wK)iC!14#^G>>kU((d}N-LXPfk_@YzC zyeO?lgw6BVOz|cMbx`i8?;eO9yXV${GcV-*r1PF337( zq*&*Xxp1j#ASSWd8DO!L-qAE&UexV%>b;e7SXxPl;!$bSXni%;c8g59)*}OOZ{0_r zkYt%(9$}&(bfs%Vz**ZnX?)lybgQUvaS?ou%P|r2En@Xjk>pX){FO7TGaoIY6^46= zCS@k;TuLMI-&K*oM_H%Sf+r2rW=RY^f98k=sP6yk)K?fv_Qx4)GZCZ13PddGGAHMV z9uC=+YDSsP`ZBqXdJb$`Iq!*wOf~HZ4e$n-jxl8r*?3g z#WR@}T!)-&<5#{pSpV41{~`pnfvXT5U7Vrt#I1d#_2v6|BM|Qq4+tHU3tqqUY2d2e z-IMEl#W7bf5R&aHGPUK|Ff^r*!mWto(t^vuzrQw0LcwkIYW?{`bqK$^Y0i+k-eA3( zLvo|Xp-s8vD0|H`OcJXzJ*{5R^>`vLTM(aTBvSpX!of@Quw6nWZIA!$SGQjYCsuJh zW!+dtGo;?6*n`8g5;DR1x#QFnMm|&XNJ{P`o>`3{JX(oAeK=FlZ=FS%I2r+Y*YzB# z8Aw1bW z!o$n^usy(9c|6U=A>Az(GP!_lg}6@Y95}l^{xNQdlPzLzbGlC8MP=uAsI_vrNjnI% z>yZ4r1xm-`_~8L1N(7$Jhe;d9&KQyES!-9 ze72kKh>9MyEBk>O$>&aZbmInga3co2fLlu01Lac3Ct6dv@+3MO0|GCH^AzFU<28+$ zrzZCbl-#L$ehKc%AvfgM0$LQc5X&0-ueY3?VS&~!_n$~H+%>ZR@5ye zmrkG44Ia0q?bk+K7)#*^WqBG=fT{jZPymOeq{4L4x?gF=#;RwSgQ{qICoh_ocS^YUc_41kuIi5b{)yFQ_^l@X6(=@4 z$G_Krs?i3frcU-~LC_{ATm8$C_w>RkrY`GaQ1*f^@4XhFl~y{(b9?)vhK!4g3{?Fu zRH#LrU6Li;XcUoo{-H26LBK|2EWpjKc_}^gd{~(I=*#&|{ z`1cRG6xMFHdOvCuYeO%hwX43yOU=pWO_zeG8U`Zr;B&fL0BhoZLNVT%YlneIKG!F( zMFfa{0+(s0#G@tQ%j5-zgLR#qG1F*SkI72w_9RZz*mV#@3B67ah{2X5P<;0oAEa`; z@H-D;EA{J~Lji#6_5$2AvsYQS@~Es|%3Nhyur{8Mn?Z{X{z$QMD%DORjs_dPV4TIgy0@vju6 zv&Pd+Lix9Bc5|)4xFqu(kq&c!U?&Ff$9WDF9ft@Y{rJfYuY+V#LD#Y=sm4_r*Ta?J z&K;g|>q%}X$f(&5;*$BD-aj8L(SN)5LAMHCby`$XE9d9)zR|qrEt_|tpOlu}{)kpM zQq?JKJb^D;_8|3xzEnQbPq}q(svgi((NtdUW?a%AQwq7Of7jVVgcC8}1CzgRNUv3D zkhZWCXz-Sw!BBWR6-f!zpCNjrJZg6YEW8A8a^^i>ZS6a=3z)%XRO0FG5kqG_y@+%D zm29za0Aj2pK&zA~*CS`z!$}qo9QuVA-*Omkjtxvsf(%P2txVzL1cmrq)SL2fzWl~C z*yQ5_rn53t^D&9r`l;#!i1hbnSCJAR4khp17B9)@lk8}S972(};SB}9V}W2aI0oZ! zKzr#=1q(V`U5J6VjKAV>mW}BGdN#3Z;nCi(a{J!Ouw;Y#J|&ItkexLNyB=QElzq78 z&vwH$Meh~*{7o%>na*Q{WG+d^weMe_W63kDf->=*6Q07Bf)P~BD+2d2rTzK9%vM45D5v1AqwG z@38A7nRRj+xGfUv7{1D&cKvZ}X>qi}=F3*SQ_8GY=koW1jY+E6QA3~U@s3B(EHO03 z&0xc{=9=XKuWgvHSr;BOPl3$MrrO*5k#Ay&V`K*u)QOUOz8{#1_{;^3YBPJ^J(2HC z<$KgkbDR7zQz6goyM3-0DNih)rJ9x#oA*LZmv_6~&~X`5n8_a7zdG4_!AFwQGz}Xa z&XFY?&ldJPDznnt`I5Q*`?OKvx`RxI6fy5Ju|8g?wLLx9Sj566kFv<{(tK<+Hc);_ z)ro!M=R$X!?2G3|Q)1XLK^@ZV{(Zv-?obOHYC$HCcePX;mf&L!LsoD}>$>?9=K&$d z)4K8pG`hmKEuB|}ByqIzxt5k)N-BR)ev8L*cias0;k^l`K14OrjkFmbQ#?wmve~WM zI-K=sas}IKk=rT>lh6CCIzpU&$37FWLsy`b)JJ?T>IrLg1}R$0#GR^WoOBIATLxWi zCioo?*PEYR^Yb`*icUPGUNiW-;HPEP01Q3yr?3$ASQwY*Ue=ePT=^bj!9#hJ0@d8G zu^NYbLTTJmtMLk@DO*F~l#7Avs;s8-`CLh#)*ue@YsA3?tGIQuc2h*`dc5IGrUv+8 z@AI!=NM(ryrn(NeO&DxV+BQ9?b>3hZ+|Z`UoNLb0`&KDXVv9cAde^F_vmck6SlD?z ziHMp_q3yic$s{Y=dW&rI*_Q>&>tX@4PEI99;k-i$xQOANnTDHmT{dFET7fodlir73 z7iY(az?+jC4STVIwh?7_qa43I_?$r_>LeyigXaFzJ@_7mpatnT*Z7w&fd*jaR?!(u z{vKNmT5P(Ny`l3D?nKswX%%Tcc%g*j0CT;op$F(5Wug6eiFQzbFnPd8gIeb(K37nP zob5^7AYxK!e))U)#@{I%tmqWmoeb69fq7@P4EGQm?Qh$Fs*{o0FS7nsOBh z#N*ai?g`oGQaR%Kmp!1-OH9m|QTyKVkmbfky2obug@R&JrFt{g>pDRcFwZ$r za~d}nSVm1?hQB^AG8jCjhj(0m+AapU);((St@PdK86 ztL^65#N%v`g)> z9{cp-&rP9uQulGwN&N$FXF~6#50ieI0zomHi-Aj|c4uikw&|3=G$EolMs9sB5k=>C zmv_*ErGT}ZElN)o#`VVN0%Ny3NlWtuo@X(JwEqpxmZ^e@tiwnW%*OvMuW2#4mQUfcjcLHNh>eBJMH|@OsywA$;!22n)GhLl-7!Z2IohDkNlAPQZZ@W zxJNR2ZBq1bU}LMJ(zDDO;ZQo%@$HtB$K3$enl?jE-`9ysi}S&=H7xa>cZoJnOPhB_ zuqX~XS?r!zOx3&Xvh5!K*NmjPABts34R6=o)V>>{Tpy3SEnuLM){GT)VS=)qE#OMq zeEy}uNx7~jI`|E4lVsvC6>@g8u^vfythJm?!L$$dD);+KAJ&Hi(>SOk(YyzoL+WV7 z_-KEga5Em~-UX)uCO`#orOaQiLUfJf^&cs^kKsp^cigf^E8TW~(Pv!6XhH^$G5f(k z0Vbu4nPw5aTy>V&baJB#uq}L-w~Sk2nB0T3GtEw?xua~w#>-zT7-AIoTOPifY4&8( zG%=+(UMVV~6?uvFDRMf%JIcmUcfhMNoaWc^$R7F~?0Y4N9}US~XY%_pe_AW4V_&J? zz86gc`GSRFz)Q;lzX|w@OwqC7{dwACz>D5POkBUQC$s(5s$!AE!1X8Ev20TJ%>j>A z!NwOFp8Q>F;hHe^jCDU_y(W@J6lXVxZj3vmIL3=QH}9ICBrCEpiErt69UEg^v2XT% z^_n=F$1El{Tiucfr8wHm`f-xC*Cliyc6Up|?Nfc5=W=mc7f-Hh33EYhkyPLnt+<2k zw-nedjOiDZ5VsT?Dw4DlN*wfMM_eE&`fyE1?Kj29hE8w?(3KaZoe>F(cov>RfyTCK zTgm@I3dV}udIYKRdx(055nXqv0IkHZ(k3VflK^C(P(hY;F-|A$J-e(#$t!BI8;A6L zhj6=!NrWL|>ypk9HTh*a_d3f){S74Am9bLsi^#GJdFXAv-hxgO&k98CiGF<+8hWJroQz*6=5X`#BBKV#r^VWt4*Fv%e?( z-*TycCJH$1tKq*I#Q9B!{t)8;CMqNzSM~o_4+ayw?VZlYXQ2Qdl3E}8o_U`K#4H2a zTY`aIg;f zUTo07A3lADeeWJU<=?P=aA!ozFpyyJYYI;|@J^9gub8!k;ExlS|ARsv(!n_r8Us8f ze1_CL6r2)5-6|WW_2ojR9a<-#nn}7-<@4`?& zPa*l9f&0pRMjTOq)9a|Rkm0>O2%Cbkjs^)O0p5Q5CE{rOqeX5tGqkeiA~T)K;O;9* z;?8h?_rif&tG7JHt$TRVKz(&4!T@;$R)>rQ-}+>g@_`twHy&^A8x{(8w`DZvjfs(K z4UoMftAna?Rt1;?Ag{n_iq3ibnmTJjD*ePeX%^Vadm6-U6gL z42)VFK&QN5Yh+M34K7cSSUTF7hgtNe%f3Kq(D|H31)V83mA(U&dPiWMvW81wzSm|4 z!CUf2$A!}#Ifhl-EAXrt2#S~+i)AY7@A1@{KvH3Tpb;K8GZsVw7|}K2v<--`6^k1VjE|11oa0)+aXqF(BR&Eya8Nj{FSugK{6D5 zUIUq;syVc0tK@zq!d=wrjRAPDzm*V5)a~xuL7w}>ZD1E8kfEVW=k@FU5NgkDQD}p^ z6FY*o7&Rb({!0KP+)kgxi`8Xk03!_LFwO%=T)NrDzVmkb=hyF zhKBJEbTy~!dma#(%{5yD|1Hiip*LtnB-CW87pf9qa@n>1<6q0fNP-RXp?kYr#I>Lg zoskrbJ(zYH&mxw#cp=?#7Tyt$(!1>v@+u#p0Zqv0+I4sM(GrGs7aFZp;PvJEVC5uW zdB_kH;|2u$7IVgLd#~IQo-Jr2!>VWM1+#Qyg7Zbpc(Ci&emXN}!F&WH6hMeb4tR9* zbIdhSLX!ZKp%QP3;xiZyCI!=d2@t}+eFzn*n+1-L+w94``QLbzFXyaS5lJTO(3VKL=cow z+N0lxKQ{xqEQeUJXj&H2(gWlSOyYr_WseSYOkzMB{63}03k*c&u`ER91n9u6mJP@u z^(>}1UXTjN(156kDVf}MEsU$1i3#4F$@V(E((~9JTBv#-3XB?^&k*5Zse+oM;Db1z z8u!C$ut%qWLO@lrJloV%4fuw3Vl6$|%Y(I1WlDfZm$y2B1|d;u(9ovHGflr+yVF5| ztd%1g`Q?(HR$4J%ob4)SD=K4sv7}LRud!b=n*ib7^SmNlD;-M7N~IFNOZ|7ss1c80 z5_gpcwQLv(2mAM89Xb#)1&&GVa>UCNPu&JTTWYxp?m>LccBGNq#bBkiZgy!D0mDP! zfJGkTUN59@Ap?`oDb-OF+UH?rA|Q`c2gNt>=;6!wtq{|Wh#XMM=lASgL%qrS0(?(! zlAv2ffk8v{Ae+zvckjHs~MybbB+dRwv>*9=J7;oum??( zW6CGlIEHT5BFzsA%h%xOog;^$WLvXMhQNT)Klh<(CicSrCbs?hreMQRtDYe+^5*s< z>%4h9`^7l@cwp+B919XrR+D6;XM|!GB{Go!X=1_$#ONGH46Gqej^d#KQ}K5M+kj{4 z0`*-#2#XTawNB=>uvb67n1IqQD*D!9_y&@A-_SDjdJ>L3_Se8LiCMaifOZ#qR)2JU zIGZc{t4QOWfO6^H!%>&jZ_H$ufJil`Y;Xhv@ms~AQa(x0ar; z&3t50td|pH(D<|++wqMf(0Kt$Rn zU$_9Xr!*W9e~U_iGM!;aE-DGS#qU(vGfUxZ@MxuRfD*vPLKf{Q3ro6&6cp)^K!K@mBEh8XDFeUOO?2Zf3Aa zQ1rh&yj}Nlghe`@b2PkN3tlpC7@EzrX4FV|55o=u)OAV|r9`I5cwDgR2}rI!A@UG? z0;D{)*3lEntq8J5ZNO2o)#kD>aeuRJ3&M!gB5teOP7Do2_~SyDK<@a}_J-t_Q@Pjj z0Buc-;&`R)EIVjah@pp%3teU+K!1VQ93X~&8D*&zs^&^m*-QhA`KcMXdt_dqfi_#9 z+ftTzFvHjG>$kChUqKb=Zt2Sa9+dCpElrlAB{0noPwgQjlR(mUT1P4)UqbuKjQqO_ z9m>Zq0o#l4w6k$-X?82ot?DbsCF7Dvr&tH+F}CxIN~JgUIG;}wq9q>Xz;X~4xF-O} z&gWxgS)Mz5pbU&drwv%R0TB8R7}XW=@TKL7t4w|U7vkjFNk-P#N%p+<3n8gXkH5yn zo}p$?iTzc$kHw=lrfm%8N1qwr#?dGE#|GJELEj7830FV5Q{}ia1Ot61L}vGX{#Q+U zy=vgS0jK7}`8b;5f)e#Y0<>h_GIl(IKl}mgFbv5A0;e!tdy*eg|3lIan#J0*@6`+E zLdtO3$k3uI#Pkx#<|7{U@y>GvwO`-9#azjOPm!OpIRU`B`EUr5cd( zh@OELbwKD1NE};jumH(|zZm^*JJ?vf|EkcgfcbUg`u{Ty{5;B|aDyA$3;2Dv(Z+#pIDGQ3E2U3Fsz4mIzWnRA7dS(hf_I@mzomcn`e$(Evm( z9`#BPl~EEwLVe`P1bG2u7o;i+)(prd$Py!#5NVE+cKAkt- zO)10w)D=nvdN%M8*-Xl*yn}^~aSV!FCpm;pY^ARJ+wezWrf*W|7`J9YKbhp^#d-Tz zo>{gM&<=H6W!U6BH&$*c_t-8xjs|n3tmsH@|ay; zSVU&N1)l%x{leEk8|@A?jp;@EfAD;rRD-%==U-i4nyPN;!{aw|9&u2CblYVMtGAiv zUjZgCo?Ddw@??|AQi<@va{M2rp;RRTbp;~{~0fqG$Vl7Nd% ztk>Dmj(r9&$c6mxdcdr-|8E{Jx(J_8+fB z=wZtZ_cq=>5d30?@|82#hmnn4Ipg1GDJf2WLJEQ13mWW)z^JI}5rkXZ9Q*b$b4~Mt z|E1xNQSaqbk9M^}H3la5HBn+u27G!rs2XCukyI50k4^k!8gTF-pl(RMjGG0JE(wz| zt>TIAGqfnhmqV&vj>sLzD5VQBQ~R9Rb>h6zKRw(c5xzY8=nDD;b1pMQ{VD5^a2u)o z9sOwWZwI|x;n~pd(W7g<+MlbDv^vQMKaLi6Vcw?q8dqPZzZZ+T{3Na61)v9wWH0TfgI- zA&qsk*5-%zsGOLXqVEb=iL_^XKC@cWN#f6$<2RnfbrDS9Hx~=F&oidDE~FUvRtw5A zsT|KK5loFS!~NR?)?es{OjG|W6Bvh9Now4$zF}4>+p&EQ4Lar#sLrA_-TI`OY z&$&j&&f5>33O}$<;H;%YG(KnLo=4Npk5#&sKzYa&)q%A`{^TVuWOdBF)D?hHE=3MC zD>`e?-^YbK1yk;8ABIL9ZGGihE9*Kp4!Zkl3LS~7x>=VYNlYNm^)3M$lB`_k#c$JB zp}20P)td%L4l5=JJKL}RjIE<28EGm^V0uHEzW!_e24kOSHeFeq-~oyPX(Z*?MCK%< zT)xo|iD2s-q0{w`O5}4QrJiF_bKloAn>eijuZO;Frbl(bDH_UT&I!-df{DgxmK<8Kd1NxU z%;9D`gR*}ng;3vN${?F`f1Ac1FL(MgDql5UK_wp5kL5_=%i6PSShniBgKK4l=;FD_ zGX@UX`NcukwLq&QMG%em5v@G+X0?`k0*i*()UOYQ?F~Z;nYVYiBR^wqj|K~kIK7_< zxK%pOreCX`Cw#mRXHSYhNh+syu)bjZr4l`xobO3f$b6kwg@aAu0@~T8|E=3~Uu=P| zT6Tq$TGAa^_dQPGUyw@B|Ks=iPK)Pw?(N*>8zz0+o0*T5k@@$i{ma0GAXrpr<<@qC zy;h7Hb&JdlGKWk> zHHtcTz0}6X+JBf6!e@-!jSmv){WkqW0ecL$Z=d4&g;kCr^P#ar28Y~q(NZm#oZE^C z7|9uE``jDR%_s|DvW$OJLU=t~(%E$^VS0&oEwDj?;1u4PuxXb-au*124spH;$xvW0Mqf|{$(&yHzbwX z_}u$^e^l13=Fei@WZwmA`E}OMO!u39C6h(iWiN#N<_fXZ zC89^@61Xx_voxOgNys>70V8{uy`~j~fv#{Y-$K4el*X2}Q9wFbP?aJiAOHy9z&fQ< zZtZG)F7vC|LrG@!3OOKEsDFbPX78AItS8iGTmk0TxxVoT&`jVZKx>AAF=WIrUm4xq zvH=chqxcKzL}8p!aH;Xr8X#Ts|1Lo#AN3-6!M`x=e`Znt&4K@Kh#1)poO7j&{hx7& z-G}r0U-DVXG17C0|E5;CvG9Odi4HUy$_@gj;~>%*eK;shlTZnYr*IIiLj<d*^Xf>D=APtlEr_3Dl417I96 zd>fdqgwd_f1g~lP*&1x#KbGbV?n7Xq8;UsIU1~=%gR=l4@E-sT0^U^1)G9r$7y-Pa zdt0-!&wC!%mps8~*moq`^P136qU?9Kz0)zMOpN}K7`vGXX@Jxh%rxr@MXp)7~$*1)z`zg^*c zd43oU+9?d8i0VPNudFjwyyQSQB`y6DXrmwi_BvUXBEaZ|fJ-K)Zd&9H2O#SXkl9M- z*E%#ov#|hUNzE^EyM-=%GSDQNlO*I(+3V98MFj(DV-$x0>AS}-?jh+5k9}8WmECDk z;H+}ABjqv+@mv`L?(G}9OUlCMj3+@CE;_BWxsjSP7&{#%}L@a{_gorEk zW$}g`D|&CBNffce2bK@OxoH9_xe7+KmgckkD|5>A$D5=q`c2*qdsRpSM>wi`#fcz` z0o&e;bqt;xRj1(mrL}xE^`L5DbD$>#W7?x{?W)LayE$Uo!Lj_4rqd`4Era-1;>@EfXGF2emk5JL0Xm@$-pjzZ zK_{j`4-(bNHA~TL5<{^c=y88m>7Qa<_BG8#i=X2Cj;d+r6l5b0^7bZe0HCL(+y9m~ z|EPTkAHN8`MWif4Gvc=0g1#7iQ0>KhrQiQi{JOV9VrV;(gq;t=fHnK7C+#;u5S!6* z_VA9q+y39LCs(8RN`MBl?$T|Nh6~(3_p$hIZgOES@o)YMrN2Aj{zs{ktDF+($oGL; z)#%eAI;_$AA2d)`8yW`iH{b)Pn>F}W4Qw1aM_@g_3g$fJpbul`WUZ9K+IYM60%<-5 z*5Oc)+sxKz${n&uXn+2psG+<6jWI(E1E`AEwmr&_rC$T*9>Lm35#v=@9#lhyhUeoI zxo7<>z%UA{cHM#PUx*%n+;Vbo1JIrskv2;} zoJ!U?Z%6>fqK!~l@XdW(VdM=?YF)P2`>(M*{lp|2e_rAPT-S&r&|>CrKqKs3|B+)1 zu&hYx_|p@cDQ$&xLB4Kk$8$^$C=QFE7zPy3@F+)z=I%AH(R}iK&=7_sZs9bJTFADf zFwow{Z`X8gy^hH-=xelkIRaKa^IUGCf&Cob0w7c;@!?4Opw(DeOZlnY&o5|$wN94I zy&)Mw9-3h(S4M?Z=6SU1olv`a-hxETw9NFf#OX>;fRkXU=wns38S8;!XLnyE(P?n+ zAqKG4Cq5UUx_d3}jIZ08Y9&c5fi(#OJT&k?2#I};6x=_5*i>iKa-DG#-MtVv6V+8G zKwPCl`aSMKA;6sK3iLEdP$RaRMhh|6G@U!U>Dx4^OOF3OBqctSO+{n%h`{11*6gdP%n&+ZgKnc>wFwH0jR8OC@KJxa^zmJa{T2oNCz`ge?iw z^99c`cx!aO@THysVN`e%-V|c7CmbXYd5?j8)Z6l=wAw(dUN}3L_-siv8AB_cgS`ZK zK5&p_3&7bjd|!aeHIjL1VAGe;c)?7GI}30BmW-LG~qr zrYZ9w;gvG;ryavJ!GFdhh}ZOa$`=Kcf1DH~YUn?rX_TL(g|C_$ve=AA;rO^Zt%QR0T_CuH( z+yty!VW2N%;<7rnRFaHm{Wqr@n5jpd4n2`=}#a6hXULJhTDw?BqKSfR984G zg5n6c-;iH`H&CJ$&w++a1Tj-Vurrt6_CRYUxDRk*{HGV~-J9L6mAb|+ERmpfuc|9-C6qZMd602A8QreK73!C~K zDQKyIP&P-m&X5kSeT7mk>g2A_Kdc$%=k2rJ=O>{6L6V)HclGp(QEqWa9&g2j!p@d5 ze8P}89aPgFNBa537B^?qs!yU96J!_73I%(QL9F+joM`R^;a zhA>0Ao}izeL){ul`9wf(CQ`QqTUow|-)XfgNb)$TxyG~!^wd&ppm2!T*6#!rXcWDz zUVUG*u#>Nl9J^4VXBmKg`-7twJL=%y$pU$m9$UH z4ursGV)5^Ny(PoHbROb63RmcoSgmg&DryWqE01xv-U&nGW@7S{{;x<~i283*S3FmK zq@Oj4*0D_&^oh)NDgVDGb*Z`jN$SpLsY4jxi5wi~57mREY=Ee1PpW)~>;pnNWTOAC z-p)K6>bC9U(jAq3uWV7-HAPuN)+l1KRvOtOOZJ^xDx}Cxgb>-IVvLC*WNdA+D?7M?Y_o^9$9QII@=Xjz6(EAP1%}~5-#-~NE^eMoyOVC zPcQS1`DbPvzEL2IF5O!yfNlvRIZZ4Uj5&W0PM*bsw3s+pNsQ2sMEhL&l~< z?E*CHx(jo+4Ik?$*3ofDeaT#&1rN@dAI`%BX&c1mG8-3$we>xlEX6aZ?lJB1i__%X zu(=uRDJ3513zUDQY-jHAu9Ku)$~~LXuC2)nL%ek>S7KJYaA{vDa|y08B#SP!2+u`v30bhr%AIk!s?%x4_DjiR5kbg^c*?e^fQ|eq%_*1 zpl;S3bLE;$;`?{(a(7TLmgHRIJNLqI>R7j!B%=RfgOkwlk+c=3saziTw_XoT zTa66I(U%qusU$J{p}KrdXUF~a8Jvx$6pw9|ADP`(Qv;hU$*G<(!Mul0KmsIC4hD1k zzllN|G?+)HS@xEBP3SunJ=?E$9&%Al8oKSdeUG&~IjhQ|6&}-5nU9cZ?SL0rOn@T9Y0`uwj9>RlIp=gpP|T8 z9I}0druDqXo3`ahbIQ?uuXcjjJUp_Z}EO(PesL|9jW)z0^hSGS!`X3R~)>)*GDAVt{r4u zF%@8(Yj@yI8Z<4Yy`?!@y#UgfM!>Nw!j!(k^#$?%*m$j8vBmq$ojC6C$5e_WRlL)xBV8piuSi@ShA`Xz2f_C{ zBKRKtd%?GhB>2vqOgLo_CPxx{Ykvy9l>m;I@7)mTl}(o~rNEAO$B~O@wETvNm;|?JP6*88I*C4k zZikF4?_x6cy*ep}fs!jKwb`vpp31>)>XiG0(!JhG7-R(_?UDxxrcVkqOZ{&M7+Di3 zkl?R4N1@tV^(jU4hOACZvpWdFJi9+7;

DnVYhBXOfIe$$_LYBWZH?MFk~h1iKOp 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 From e5ce872868bf2c547177f3097ac9a3dafe0c218c Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Fri, 2 Dec 2022 11:49:59 +0100 Subject: [PATCH 37/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: tlohmar --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index 823793078d..fbd26eb659 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -23,7 +23,7 @@ The URL pointing to the RESTful resource of the QoS API. **Authentication** Security access keys such as OAuth 2.0 client credentials used by Client applications to invoke the QoD API. -**QoS Profile** +**QoS Profiles and QoS profile labels** Latency or throughput requirements of the application mapped to relevant QoS profile class. **Identifier for the the user equipment (UE)** From 1c8c8b4efc0a829a54a02a329ce0a240ddfd46c2 Mon Sep 17 00:00:00 2001 From: Herbert Damker <52109189+hdamker@users.noreply.github.com> Date: Mon, 5 Dec 2022 15:30:21 +0100 Subject: [PATCH 38/38] Update documentation/API_documentation/QoD_API.md Co-authored-by: Jose Luis Urien --- documentation/API_documentation/QoD_API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/API_documentation/QoD_API.md b/documentation/API_documentation/QoD_API.md index fbd26eb659..382ca6973f 100644 --- a/documentation/API_documentation/QoD_API.md +++ b/documentation/API_documentation/QoD_API.md @@ -4,7 +4,7 @@ ## 1\. Introduction -Industrial (IoT), VR/Gaming, live video streaming, autonomous driving and many other scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable latency (reduced jitter) or stable throughput from the network can improve user experience substantially. +Industrial (IoT), VR/Gaming, live video streaming, autonomous driving and many other scenarios demand network communication quality and are sensitive to any change in transmission conditions. Being able to request a stable latency (reduced jitter) or prioritized throughput from the network can improve user experience substantially. The QoD API offers the application developers the capability to request for stable latency (reduced jitter) or throughput for some specified application data flows between application clients (within a User Equipment) and Application Servers (backend services). The developer has a pre-defined set of Quality of Service (QoS) Profiles which they could choose from depending on their latency or throughput requirements.