StikDebug/StikJIT/idevice/heartbeat.m
Stephen B 06b64192c4 Add device library and external device support (Semi WIP)
Introduces DeviceLibraryStore and DeviceConnectionContext to manage external device profiles and connections. Updates app logic to support switching between local loopback VPN and direct external device connections, including UI for device management and improved connection handling throughout the app.
2025-12-06 15:20:23 -05:00

93 lines
3 KiB
Objective-C

// Jackson Coxson
// heartbeat.c
#include "idevice.h"
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/_types/_u_int64_t.h>
#include <CoreFoundation/CoreFoundation.h>
#include <limits.h>
#include "heartbeat.h"
@import Foundation;
bool isHeartbeat = false;
NSDate* lastHeartbeatDate = nil;
void startHeartbeat(IdevicePairingFile* pairing_file, IdeviceProviderHandle** provider, bool* isHeartbeat, HeartbeatCompletionHandlerC completion, LogFuncC logger) {
// Initialize logger
idevice_init_logger(Debug, Disabled, NULL);
// Create the socket address (replace with your device's IP)
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCKDOWN_PORT);
NSString *ipOverride = [[NSUserDefaults standardUserDefaults] stringForKey:@"TunnelDeviceIP"];
if (ipOverride.length == 0) {
ipOverride = @"10.7.0.2";
}
inet_pton(AF_INET, ipOverride.UTF8String, &addr.sin_addr);
IdeviceProviderHandle* newProvider = 0;
IdeviceFfiError* err = idevice_tcp_provider_new((struct sockaddr *)&addr, pairing_file,
"ExampleProvider", &newProvider);
if (err != NULL) {
fprintf(stderr, "Failed to create TCP provider: [%d] %s", err->code,
err->message);
idevice_pairing_file_free(pairing_file);
idevice_error_free(err);
*isHeartbeat = false;
return;
}
// Connect to installation proxy
HeartbeatClientHandle *client = NULL;
err = heartbeat_connect(newProvider, &client);
if (err != NULL) {
fprintf(stderr, "Failed to connect to installation proxy: [%d] %s",
err->code, err->message);
idevice_provider_free(newProvider);
idevice_error_free(err);
*isHeartbeat = false;
return;
}
if(*isHeartbeat) {
idevice_provider_free(newProvider);
return;
}
// we mark heartbeat as success and set the default provider
*isHeartbeat = true;
*provider = newProvider;
completion(0, "Heartbeat Completed");
u_int64_t current_interval = 15;
while (1) {
// Get the new interval
u_int64_t new_interval = 0;
err = heartbeat_get_marco(client, current_interval, &new_interval);
if (err != NULL) {
fprintf(stderr, "Failed to get marco: [%d] %s", err->code, err->message);
heartbeat_client_free(client);
idevice_error_free(err);
*isHeartbeat = false;
return;
}
current_interval = new_interval + 5;
// Reply
err = heartbeat_send_polo(client);
if (err != NULL) {
fprintf(stderr, "Failed to get marco: [%d] %s", err->code, err->message);
heartbeat_client_free(client);
idevice_error_free(err);
*isHeartbeat = false;
return;
}
}
}