Skip to content

Commit fcaca86

Browse files
committed
fix: add timeout when receiving message from connection
All socket connections were changed and now are started in ssl mode. This changes the way messages are sent and received from sockets. As a result, `timeout` option is not anymore respected when receiving messages from socket. However, the messages now are received only via methods from mobile device lib. As there isn't a built-in method in mobile device that can work with timeout, we implemented timeout mechanism using new thread. `AMDServiceConnectionReceive` blocks the current thread when application is not running on device. After the provided timeout, the socket connection is invalidated and this way the current thread is freed.
1 parent e221d70 commit fcaca86

File tree

4 files changed

+22
-4
lines changed

4 files changed

+22
-4
lines changed

IOSDeviceLib/Declarations.h

+1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ extern "C"
267267
{
268268
CFSocketNativeHandle AMDServiceConnectionGetSocket(ServiceConnRef con);
269269
long AMDServiceConnectionReceive(ServiceConnRef, void *, long);
270+
void AMDServiceConnectionInvalidate(ServiceConnRef);
270271
long AMDServiceConnectionSendMessage(ServiceConnRef serviceConnection, CFDictionaryRef message, CFPropertyListFormat format);
271272
unsigned AMDeviceSecureStartService(AMDeviceRef device, CFStringRef service_name, unsigned int *unknown, ServiceConnRef * handle);
272273
unsigned AMDeviceNotificationSubscribe(void(*f)(const DevicePointer*), long, long, long, HANDLE*);

IOSDeviceLib/IOSDeviceLib.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ void get_application_infos(std::string device_identifier, std::string method_id)
10071007
std::vector<json> livesync_app_infos;
10081008
while (true)
10091009
{
1010-
std::map<std::string, boost::any> dict = receive_con_message(serviceInfo.connection);
1010+
std::map<std::string, boost::any> dict = receive_con_message(serviceInfo.connection, device_identifier, method_id, 0);
10111011
PRINT_ERROR_AND_RETURN_IF_FAILED_RESULT(dict.count(kErrorKey), boost::any_cast<std::string>(dict[kErrorKey]).c_str(), device_identifier, method_id);
10121012
if (dict.empty() || (dict.count(kStatusKey) && has_complete_status(dict)))
10131013
{
@@ -1181,7 +1181,7 @@ void await_notification_response(std::string device_identifier, AwaitNotificatio
11811181
PRINT_ERROR_AND_RETURN_IF_FAILED_RESULT(connection == nullptr, invalid_connection_error_message.c_str(), device_identifier, method_id);
11821182

11831183
ServiceInfo currentNotificationProxy = devices[device_identifier].services[kNotificationProxy];
1184-
std::map<std::string, boost::any> response = receive_con_message(connection);
1184+
std::map<std::string, boost::any> response = receive_con_message(connection, device_identifier, method_id, await_notification_response_info.timeout);
11851185
if (response.size())
11861186
{
11871187
PRINT_ERROR_AND_RETURN_IF_FAILED_RESULT(response.count(kErrorKey), boost::any_cast<std::string>(response[kErrorKey]).c_str(), device_identifier, method_id);

IOSDeviceLib/SocketHelper.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,26 @@
77
#include "PlistCpp/Plist.hpp"
88
#include "PlistCpp/PlistDate.hpp"
99

10+
void setTimeout(std::function<void()> operation, int timeout) {
11+
std::thread([=]() {
12+
std::this_thread::sleep_for(std::chrono::milliseconds(timeout * 1000));
13+
operation();
14+
}).detach();
15+
}
16+
1017
std::mutex receive_con_message_mutex;
11-
std::map<std::string, boost::any> receive_con_message(ServiceConnRef con)
18+
std::map<std::string, boost::any> receive_con_message(ServiceConnRef con, std::string device_identifier, std::string method_id, int timeout)
1219
{
1320
receive_con_message_mutex.lock();
21+
22+
bool isSuccessful = false;
23+
24+
setTimeout([=]() {
25+
if (!isSuccessful) {
26+
AMDServiceConnectionInvalidate(con);
27+
}
28+
}, timeout);
29+
1430
std::map<std::string, boost::any> dict;
1531
char *buffer = new char[4];
1632
int bytes_read = AMDServiceConnectionReceive(con, buffer, 4);
@@ -23,6 +39,7 @@ std::map<std::string, boost::any> receive_con_message(ServiceConnRef con)
2339
if (bytes_read > 0)
2440
{
2541
Plist::readPlist(buffer, res, dict);
42+
isSuccessful = true;
2643
}
2744
}
2845

IOSDeviceLib/SocketHelper.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ LengthEncodedMessage get_message_with_encoded_length(const char* message, long l
4141
int send_message(const char* message, SOCKET socket, long long length = -1);
4242
int send_message(std::string message, SOCKET socket, long long length = -1);
4343
long send_con_message(HANDLE* serviceConnection, CFDictionaryRef message);
44-
std::map<std::string, boost::any> receive_con_message(HANDLE* con);
44+
std::map<std::string, boost::any> receive_con_message(HANDLE* con, std::string device_identifier, std::string method_id, int timeout);
4545
std::map<std::string, boost::any> receive_message(SOCKET socket, int timeout = 5);
4646
std::string receive_message_raw(SOCKET socket, int size = 1000);
4747

0 commit comments

Comments
 (0)