Skip to content

Commit b320fc1

Browse files
committed
add request_directory() for file transfer
1 parent f9de691 commit b320fc1

File tree

4 files changed

+108
-0
lines changed

4 files changed

+108
-0
lines changed

c104/__init__.pyi

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,30 @@ class Connection:
933933
>>> if not my_connection.test(common_address=47):
934934
>>> raise ValueError("Cannot send test command")
935935
"""
936+
def request_directory(self, common_address: int, ioa: int = 0, wait_for_response: bool = True) -> bool:
937+
"""
938+
send a file directory request to the remote terminal unit (server)
939+
sends F_SC_NA_1 (Type 122) with SCQ=0
940+
941+
Parameters
942+
----------
943+
common_address: int
944+
station common address
945+
ioa: int
946+
information object address (default 0)
947+
wait_for_response: bool
948+
block call until response received?
949+
950+
Returns
951+
-------
952+
bool
953+
True, if request sent successfully
954+
955+
Example
956+
-------
957+
>>> if my_connection.request_directory(common_address=1):
958+
>>> print("Directory request sent")
959+
"""
936960
def unmute(self) -> bool:
937961
"""
938962
tell the remote terminal unit (server) that this connection is not muted, allow monitoring messages

src/python.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,6 +2393,34 @@ Example
23932393
)def",
23942394
"common_address"_a, "with_time"_a = true,
23952395
"wait_for_response"_a = true, py::return_value_policy::copy)
2396+
.def(
2397+
"request_directory", &Remote::Connection::requestDirectory,
2398+
R"def(request_directory(self: c104.Connection, common_address: int, ioa: int = 0, wait_for_response: bool = True) -> bool
2399+
2400+
send a file directory request to the remote terminal unit (server)
2401+
sends F_SC_NA_1 (Type 122) with SCQ=0
2402+
2403+
Parameters
2404+
----------
2405+
common_address: int
2406+
station common address
2407+
ioa: int
2408+
information object address (default 0)
2409+
wait_for_response: bool
2410+
block call until response received?
2411+
2412+
Returns
2413+
-------
2414+
bool
2415+
True, if request sent successfully
2416+
2417+
Example
2418+
-------
2419+
>>> if my_connection.request_directory(common_address=1):
2420+
>>> print("Directory request sent")
2421+
)def",
2422+
"common_address"_a, "ioa"_a = 0, "wait_for_response"_a = true,
2423+
py::return_value_policy::copy)
23962424
.def(
23972425
"add_station", &Remote::Connection::addStation,
23982426
R"def(add_station(self: c104.Connection, common_address: int) -> c104.Station | None

src/remote/Connection.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,51 @@ bool Connection::test(std::uint_fast16_t commonAddress, bool with_time,
932932
return result;
933933
}
934934

935+
bool Connection::requestDirectory(std::uint_fast16_t commonAddress,
936+
std::uint_fast32_t ioa,
937+
const bool wait_for_response) {
938+
Module::ScopedGilRelease const scoped("Connection.requestDirectory");
939+
940+
if (!isOpen())
941+
return false;
942+
943+
std::string const cmdId =
944+
std::to_string(commonAddress) + "-F_SC_NA_1-" + std::to_string(ioa);
945+
if (wait_for_response) {
946+
prepareCommandSuccess(cmdId, COMMAND_AWAIT_CON_TERM);
947+
}
948+
949+
// Create ASDU for directory request (F_SC_NA_1, Type 122)
950+
std::unique_lock<Module::GilAwareMutex> lock(connection_mutex);
951+
CS101_AppLayerParameters alParams =
952+
CS104_Connection_getAppLayerParameters(connection);
953+
954+
CS101_ASDU asdu =
955+
CS101_ASDU_create(alParams, false, CS101_COT_FILE_TRANSFER, 0,
956+
static_cast<int>(commonAddress), false, false);
957+
958+
// Create FileCallOrSelect information object
959+
// SCQ = 0 means "select directory"
960+
FileCallOrSelect io =
961+
FileCallOrSelect_create(NULL, static_cast<int>(ioa), 0, 0, 0);
962+
963+
CS101_ASDU_addInformationObject(asdu, (InformationObject)io);
964+
InformationObject_destroy((InformationObject)io);
965+
966+
bool const result = CS104_Connection_sendASDU(connection, asdu);
967+
lock.unlock();
968+
969+
CS101_ASDU_destroy(asdu);
970+
971+
if (wait_for_response) {
972+
if (result) {
973+
return awaitCommandSuccess(cmdId);
974+
}
975+
cancelCommandSuccess(cmdId);
976+
}
977+
return result;
978+
}
979+
935980
bool Connection::transmit(std::shared_ptr<Object::DataPoint> point,
936981
const CS101_CauseOfTransmission cause) {
937982
auto type = point->getType();

src/remote/Connection.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,17 @@ class Connection : public std::enable_shared_from_this<Connection> {
393393
bool test(std::uint_fast16_t commonAddress, bool with_time = true,
394394
bool wait_for_response = true);
395395

396+
/**
397+
* @brief request file directory listing from server
398+
* @param commonAddress station address
399+
* @param ioa information object address (default 0)
400+
* @param wait_for_response blocking or non-blocking
401+
* @return success information
402+
*/
403+
bool requestDirectory(std::uint_fast16_t commonAddress,
404+
std::uint_fast32_t ioa = 0,
405+
bool wait_for_response = true);
406+
396407
/**
397408
* @brief transmit a command to a remote server
398409
* @param point control point

0 commit comments

Comments
 (0)