|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2021 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // ホストデバイス (基本クラス)
9: //
10:
11: #pragma once
12:
13: #include "thread.h"
14: #include "autofd.h"
15: #include "kevent.h"
1.1.1.7 ! root 16: #include <mutex>
1.1 root 17:
1.1.1.7 ! root 18: using DeviceCallback_t = void (Device::*)(uint32);
1.1 root 19: #define ToDeviceCallback(f) static_cast<DeviceCallback_t>(f)
20:
21: class HostDevice : public ThreadDevice
22: {
23: using inherited = ThreadDevice;
24:
1.1.1.7 ! root 25: protected:
! 26: static constexpr uint8 PIPE_TX = 0; // データ送信通知
! 27: static constexpr uint8 PIPE_RESELECT = 1; // ドライバ再選択通知
! 28:
1.1 root 29: public:
30: static const int DONE = 0; // 処理終了
31: static const int DATA_FROM_VM = 1; // VM からの着信
32: static const int DATA_FROM_OUTER = 2; // 外部からの着信
33: static const int LISTEN_SOCKET = 3; // 待受ソケット着信
34:
35: protected:
1.1.1.7 ! root 36: HostDevice(Device *parent_, uint objid_, const std::string& portname_);
1.1 root 37: public:
1.1.1.4 root 38: ~HostDevice() override;
1.1 root 39:
1.1.1.6 root 40: bool Create2() override;
1.1.1.7 ! root 41: bool Init() override;
1.1 root 42:
43: void Terminate() override;
44:
45: // 設定ファイルキーのプレフィックス ("hostcomX-" とか) を返す
46: std::string GetConfigKey() const;
47:
1.1.1.7 ! root 48: // 表示用の親デバイスのポート名 ("SIO(uPD7201) Ch.A" とか) を返す。
! 49: std::string GetPortName() const { return portname; }
! 50: void SetPortName(const std::string& portname_) { portname = portname_; }
! 51:
1.1 root 52: // NetDriver からのディスクリプタの登録
53: int AddOuter(int fd);
54: int DelOuter(int fd);
55: int AddListen(int ls, int action);
1.1.1.7 ! root 56: int DelListen(int ls);
1.1 root 57:
1.1.1.7 ! root 58: // ドライバの再選択を指示。(他スレッドから呼ばれる)
! 59: bool NotifyReselectDriver() {
! 60: return WritePipe(PIPE_RESELECT);
! 61: }
! 62:
! 63: void ResetRxCallback();
! 64: void SetRxCallback(DeviceCallback_t func, uint32 arg);
1.1 root 65: void SetAcceptCallback(DeviceCallback_t func);
66:
1.1.1.7 ! root 67: // 直近のエラーメッセージを返す。
! 68: const std::string& GetErrmsg() const { return errmsg; }
! 69:
1.1 root 70: protected:
71: void ThreadRun() override;
72:
73: virtual void Dispatch(int udata);
74:
75: // ドライバから読み込み。キューに投入したデータ数を返す。
76: virtual int Read() = 0;
77:
78: // ドライバに書き出し。
1.1.1.7 ! root 79: virtual void Write() = 0;
! 80:
! 81: // ドライバの(再)選択。
! 82: virtual bool SelectDriver(bool startup) = 0;
1.1 root 83:
84: bool WritePipe(uint32 data);
85:
86: // ログ出力
87: void putlogn(const char *fmt, ...) const override __printflike(2, 3);
88:
1.1.1.3 root 89: // 親デバイス
90: Device *parent {};
91:
1.1.1.7 ! root 92: // 親デバイスのポート名 (UI 表示用)
! 93: std::string portname {};
! 94:
! 95: // ドライバ切り替えから保護するため。TODO: rwlock
! 96: std::mutex driverlock {};
! 97:
1.1 root 98: autofd kq {};
99:
100: // VM からの送信用パイプ
101: autofd rpipe {};
102: autofd wpipe {};
103:
104: // 各種通知コールバック
105: DeviceCallback_t rx_func {};
1.1.1.7 ! root 106: uint32 rx_arg {};
1.1 root 107: DeviceCallback_t accept_func {};
108:
1.1.1.7 ! root 109: std::string errmsg {};
! 110:
1.1 root 111: // スレッド終了フラグ
112: bool exit_requested {};
113: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.