|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
1.1.1.3 root 9: #include "device.h"
10: #include "qvector.h"
1.1 root 11: #include <array>
12: #include <mutex>
1.1.1.7 ! root 13: #include <queue>
1.1 root 14: #include <vector>
15:
16: // IODevice
17: // |
18: // v
19: // EthernetDevice (イーサネットとしての共通部分)
20: // |
21: // +--------+-------+
22: // v v
23: // LanceDevice RTL8019Device
24: // (LUNA, AM7990) (X68000, RTL8019)
25: //
26: // これ自体は IODevice である必要はないが、LanceDevice などの親になるため
1.1.1.6 root 27: // IODevice にしてある。(多重継承はしない)
1.1 root 28:
29: class NetDriver;
30:
31: // MAC アドレス格納用のクラス
32: class macaddr_t : public std::array<uint8, 6>
33: {
1.1.1.3 root 34: using inherited = std::array<uint8, 6>;
1.1 root 35: public:
36: // この MAC アドレスが 00:00:00:00:00:00 なら true
37: bool empty() const {
38: for (const auto& v : *this) {
39: if (v != 0) {
40: return false;
41: }
42: }
43: return true;
44: }
45:
1.1.1.3 root 46: // 区切り文字なしの文字列形式を返す。主に ROM 埋め込み用で英字は大文字。
47: // 01:23:AB なら "0123AB" のような感じ。
1.1 root 48: std::string to_string() const {
49: std::string buf;
50: for (const auto& v : *this) {
1.1.1.3 root 51: buf += string_format("%02X", v);
52: }
53: return buf;
54: }
55:
56: // sep を区切り文字とする文字列形式を返す。主に表示用で英字は小文字。
57: // 01:23:AB で sep = ":" なら "01:23:ab" のような感じ。
58: std::string to_string(char sep) const {
59: std::string buf;
60: for (const auto& v : *this) {
61: buf += string_format("%02x%c", v, sep);
1.1 root 62: }
63: buf.pop_back();
64: return buf;
65: }
66: };
67:
1.1.1.7 ! root 68: // 受信パケット
! 69: using RXPacket = std::unique_ptr<qvector<uint8>>;
! 70: // 受信パケットキュー用
! 71: using RXPacketQueue = std::queue<RXPacket>;
! 72:
1.1 root 73: class EthernetDevice : public IODevice
74: {
1.1.1.3 root 75: using inherited = IODevice;
1.1 root 76: protected:
1.1.1.7 ! root 77: EthernetDevice(const std::string& objname_);
1.1 root 78: public:
1.1.1.5 root 79: virtual ~EthernetDevice() override;
1.1 root 80:
1.1.1.3 root 81: bool Create() override;
1.1.1.5 root 82:
1.1 root 83: // パケットを受信した。
84: // ホストネットワークドライバから呼ばれる。
85: // バッファをコピーしてこちらのスレッドに処理を引き渡すところまでを行う。
1.1.1.7 ! root 86: // packet はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、
1.1 root 87: // データ(46-1500バイト)、FCS(CRC) (4バイト) からなる。
1.1.1.7 ! root 88: // 渡されたパケットの所有権はこちらで引き取る。
! 89: bool RecvPacket(RXPacket packet);
1.1 root 90:
1.1.1.3 root 91: // MAC アドレスを取得
92: macaddr_t GetMacAddr() const {
93: return macaddr;
94: }
95:
1.1.1.7 ! root 96: // 統計情報の取得
! 97: uint64 GetTXPkts() const { return tx_pkts; }
! 98: uint64 GetRXPkts() const { return rx_pkts; }
! 99:
! 100: protected:
1.1 root 101: // このデバイスと継承デバイスのメンバ変数を読み書きする場合は
102: // 必ずこのロックを取得する。?
103: std::mutex mtx {};
104:
1.1.1.7 ! root 105: // パケット受信許可。
! 106: bool RecvEnabled {};
! 107:
1.1 root 108: // MAC アドレスを生成する
109: static void GenerateMacAddr(macaddr_t *addr);
110:
111: // MAC アドレス文字列をバイナリに変換する
112: static bool ParseMacAddr(macaddr_t& dst, const std::string& src);
113:
114: // パケットを送信する
115: bool SendPacket(const std::vector<uint8>& buf);
1.1.1.3 root 116:
1.1.1.7 ! root 117: // 継承クラスはこのメソッドをオーバーライドして、受信に対する処理を行う。
! 118: // パケットを受信してキューに投入した後に呼び出される。
! 119: virtual void NotifyRecvPacket() = 0;
! 120:
1.1.1.3 root 121: // MAC アドレス
1.1.1.4 root 122: macaddr_t macaddr {};
1.1.1.7 ! root 123:
! 124: // 受信パケットキュー
! 125: // VMとホストの通信速度調停のためキューが必要。
! 126: RXPacketQueue rxq {};
! 127:
! 128: // 統計情報
! 129: uint64 tx_pkts {};
! 130: uint64 rx_pkts {};
! 131:
! 132: private:
! 133: // Create() の下請け
! 134: bool CreateNone();
! 135: bool CreateAFPacket();
! 136: bool CreateTap();
! 137: bool CreateBPF();
1.1 root 138: };
139:
1.1.1.2 root 140: extern std::unique_ptr<EthernetDevice> gEthernet;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.