/* * Copyright 2010, Andreas Färber * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef BOOT_NET_ISCSITARGET_H #define BOOT_NET_ISCSITARGET_H #include #include #include #include #include #include #define ISCSI_PORT 3260 class TCPSocket; class iSCSISession; struct iscsi_basic_header_segment; #define kTcpTimeout 10000000ULL class iSCSIConnection { public: iSCSIConnection(); virtual ~iSCSIConnection(); status_t Init(iSCSISession* session); status_t Open(ip_addr_t address, uint16 port); status_t Login(const char* targetName = NULL, char** targetAlias = NULL); status_t Logout(bool closeSession = false); status_t GetText(const char* request, size_t requestLength, char** response, size_t* responseLength); status_t SendCommand(const void* command, size_t commandSize, bool r, bool w, uint32 expectedDataTransferLength, void* response, uint32 responseOffset, size_t responseLength); bool Active() const { return fConnected; } private: status_t _ReadResponse(iscsi_basic_header_segment* buffer, bigtime_t timeout = kTcpTimeout); status_t _Read(void* buffer, size_t bufferSize, bigtime_t timeout = kTcpTimeout); iSCSISession* fSession; TCPSocket* fSocket; bool fConnected; uint16 fConnectionID; uint32 fStatusSequenceNumber; }; class iSCSISession { public: iSCSISession(const char* targetName = NULL); virtual ~iSCSISession(); status_t Init(ip_addr_t address, uint16 port, char** targetAlias = NULL); status_t Close(); uint32 CommandSequenceNumber() const { return fCommandSequenceNumber; } uint32 NextCommandSequenceNumber() { return fCommandSequenceNumber++; } iSCSIConnection* Connection() const { return fConnection; } bool Active() { return fConnection != NULL && fConnection->Active(); } private: bool fDiscovery; const char* fTargetName; uint32 fCommandSequenceNumber; iSCSIConnection* fConnection; // XXX should allow for multiple }; class iSCSITarget : public Node { public: iSCSITarget(); virtual ~iSCSITarget(); status_t Init(ip_addr_t address, uint16 port, const char* targetName); virtual ssize_t ReadAt(void* cookie, off_t pos, void* buffer, size_t bufferSize); virtual ssize_t WriteAt(void* cookie, off_t pos, const void* buffer, size_t bufferSize); virtual status_t GetName(char* buffer, size_t bufferSize) const; virtual off_t Size() const; static bool DiscoverTargets(ip_addr_t address, uint16 port, NodeList* devicesList); static bool _AddDevice(ip_addr_t address, uint16 port, const char* targetName, NodeList* devicesList); private: status_t _GetSize(); iSCSISession* fSession; char* fTargetName; char* fTargetAlias; uint32 fLastLBA; uint32 fBlockSize; }; #endif