Home | History | Annotate | Download | only in shm
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #pragma once
     17 
     18 #include "common/vsoc/shm/base.h"
     19 #include "common/vsoc/shm/circqueue.h"
     20 #include "common/vsoc/shm/lock.h"
     21 
     22 // Memory layout for wifi packet exchange region.
     23 namespace vsoc {
     24 namespace layout {
     25 namespace socket_forward {
     26 
     27 constexpr std::size_t kMaxPacketSize = 8192;
     28 constexpr std::size_t kNumQueues = 16;
     29 
     30 enum class QueueState : std::uint32_t {
     31   INACTIVE = 0,
     32   HOST_CONNECTED = 1,
     33   BOTH_CONNECTED = 2,
     34   HOST_CLOSED = 3,
     35   GUEST_CLOSED = 4,
     36   // If both are closed then the queue goes back to INACTIVE
     37   // BOTH_CLOSED = 0,
     38 };
     39 static_assert(ShmTypeValidator<QueueState, 4>::valid,
     40               "Compilation error. Please fix above errors and retry.");
     41 
     42 struct Queue {
     43   static constexpr size_t layout_size =
     44       CircularPacketQueue<16, kMaxPacketSize>::layout_size + 4;
     45 
     46   CircularPacketQueue<16, kMaxPacketSize> queue;
     47 
     48   QueueState queue_state_;
     49 
     50   bool Recover() {
     51     return queue.Recover();
     52   }
     53 };
     54 ASSERT_SHM_COMPATIBLE(Queue);
     55 
     56 struct QueuePair {
     57   static constexpr size_t layout_size = 2 * Queue::layout_size + 8;
     58 
     59   // Traffic originating from host that proceeds towards guest.
     60   Queue host_to_guest;
     61   // Traffic originating from guest that proceeds towards host.
     62   Queue guest_to_host;
     63 
     64   std::uint32_t port_;
     65 
     66   SpinLock queue_state_lock_;
     67 
     68 
     69   bool Recover() {
     70     // TODO: Put queue_state_ and port_ recovery here, probably after grabbing
     71     bool recovered = false;
     72     recovered = recovered ||  host_to_guest.Recover();
     73     recovered = recovered || guest_to_host.Recover();
     74     recovered = recovered || queue_state_lock_.Recover();
     75     return recovered;
     76   }
     77 };
     78 ASSERT_SHM_COMPATIBLE(QueuePair);
     79 
     80 struct SocketForwardLayout : public RegionLayout {
     81   static constexpr size_t layout_size = QueuePair::layout_size * kNumQueues + 8;
     82 
     83   bool Recover() {
     84     bool recovered = false;
     85     for (auto& i : queues_) {
     86       bool rval = i.Recover();
     87       recovered = recovered || rval;
     88     }
     89     //TODO: consider handling the sequence number here
     90     return recovered;
     91   }
     92 
     93   QueuePair queues_[kNumQueues];
     94   std::atomic_uint32_t seq_num; // incremented for every new connection
     95   std::atomic_uint32_t generation_num; // incremented for every new socket forward process
     96   static const char* region_name;
     97 };
     98 
     99 ASSERT_SHM_COMPATIBLE(SocketForwardLayout);
    100 
    101 }  // namespace socket_forward
    102 }  // namespace layout
    103 }  // namespace vsoc
    104