aboutsummaryrefslogtreecommitdiff
path: root/pw_transfer/public/pw_transfer/internal/event.h
blob: 472bc59bf5a0508a0258ce9a5705915df4ad681b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2022 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once

#include "pw_chrono/system_clock.h"
#include "pw_rpc/writer.h"
#include "pw_stream/stream.h"
#include "pw_transfer/internal/protocol.h"

namespace pw::transfer {

class Handler;

namespace internal {

enum class TransferType : bool { kTransmit, kReceive };

enum class TransferStream {
  kClientRead,
  kClientWrite,
  kServerRead,
  kServerWrite,
};

enum class EventType {
  // Begins a new transfer in an available context.
  kNewClientTransfer,
  kNewServerTransfer,

  // Processes an incoming chunk for a transfer.
  kClientChunk,
  kServerChunk,

  // Runs the timeout handler for a transfer.
  kClientTimeout,
  kServerTimeout,

  // Terminates an ongoing transfer with a specified status, optionally sending
  // a status chunk to the other end of the transfer.
  kClientEndTransfer,
  kServerEndTransfer,

  // Sends a status chunk to terminate a transfer. This does not call into the
  // transfer context's completion handler; it is for out-of-band termination.
  kSendStatusChunk,

  // Manages the list of transfer handlers for a transfer service.
  kAddTransferHandler,
  kRemoveTransferHandler,

  // For testing only: aborts the transfer thread.
  kTerminate,
};

// Forward declarations required for events.
class TransferParameters;
class TransferThread;

struct NewTransferEvent {
  TransferType type;
  ProtocolVersion protocol_version;
  uint32_t session_id;
  uint32_t resource_id;
  rpc::Writer* rpc_writer;
  const TransferParameters* max_parameters;
  chrono::SystemClock::duration timeout;
  chrono::SystemClock::duration initial_timeout;
  uint32_t max_retries;
  uint32_t max_lifetime_retries;
  TransferThread* transfer_thread;

  union {
    stream::Stream* stream;  // In client-side transfers.
    Handler* handler;        // In server-side transfers.
  };

  const std::byte* raw_chunk_data;
  size_t raw_chunk_size;
};

// A chunk received by a transfer client / server.
struct ChunkEvent {
  // Identifier for the transfer to which the chunk belongs.
  uint32_t context_identifier;

  // If true, only match the identifier against context resource IDs.
  bool match_resource_id;

  // The raw data of the chunk.
  const std::byte* data;
  size_t size;
};

struct EndTransferEvent {
  uint32_t session_id;
  Status::Code status;
  bool send_status_chunk;
};

struct SendStatusChunkEvent {
  uint32_t session_id;
  ProtocolVersion protocol_version;
  Status::Code status;
  TransferStream stream;
};

struct Event {
  EventType type;

  union {
    NewTransferEvent new_transfer;
    ChunkEvent chunk;
    EndTransferEvent end_transfer;
    SendStatusChunkEvent send_status_chunk;
    Handler* add_transfer_handler;
    Handler* remove_transfer_handler;
  };
};

}  // namespace internal
}  // namespace pw::transfer