获取iphone/ipad设备信息(例如ecid,udid,电池电量,硬盘容量等等),获取到的内容保存在
varMap。 实现代码:
int MyMobileDevice::getDeviceInfo(QString udid, QVariant &data)
{
qDebug() << "get device info +++++" << udid;
auto udidStr = udid.toUtf8();
QVariantMap varMap;
lockdownd_client_t client = NULL;
lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
idevice_t device = NULL;
idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
int simple = 0;
int format = FORMAT_KEY_VALUE;
int use_network = 0;
const char *domain = NULL;
const char *key = NULL;
char *xml_doc = NULL;
uint32_t xml_length;
plist_t node = NULL;
diagnostics_relay_client_t diagnostics_client = NULL;
lockdownd_service_descriptor_t service = NULL;
ret = idevice_new_with_options(&device, udidStr.data(), (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
if (ret != IDEVICE_E_SUCCESS)
{
qDebug() << "can not open device:" << ret;
return -1;
}
qDebug() << ret;
//用户未点击信任此电脑
if (LOCKDOWN_E_SUCCESS != (ldret = simple ?
lockdownd_client_new(device, &client, TOOL_NAME):
lockdownd_client_new_with_handshake(device, &client, TOOL_NAME))) {
fprintf(stderr, "ERROR: Could not connect to lockdownd: %s (%d)\n", lockdownd_strerror(ldret), ldret);
idevice_free(device);
return -2;
}
/* attempt to use newer diagnostics service available on iOS 5 and later */
auto ldRet = lockdownd_start_service(client, "com.apple.mobile.diagnostics_relay", &service);
if (ldRet != LOCKDOWN_E_SUCCESS) {
/* attempt to use older diagnostics service */
ldRet = lockdownd_start_service(client, "com.apple.iosdiagnostics.relay", &service);
}
if ((ldRet == LOCKDOWN_E_SUCCESS) && service && (service->port > 0))
{
if (diagnostics_relay_client_new(device, service, &diagnostics_client) != DIAGNOSTICS_RELAY_E_SUCCESS)
{
qDebug() << "ERROR: Could not connect to diagnostics_relay!";
}
else
{
QVariant var;
plist_t keys = nullptr;
keys = plist_new_array();
plist_array_append_item(keys, plist_new_string("AmbientLightSensorSerialNumber"));
plist_array_append_item(keys, plist_new_string("RosalineSerialNumber"));
plist_array_append_item(keys, plist_new_string("DiskUsage"));
plist_array_append_item(keys, plist_new_string("CoverglassSerialNumber"));
plist_array_append_item(keys, plist_new_string("ComputerName"));
plist_array_append_item(keys, plist_new_string("RawPanelSerialNumber"));
plist_array_append_item(keys, plist_new_string("FrontInfraredCameraModuleSerialNumber"));
plist_array_append_item(keys, plist_new_string("RearFacingCameraModuleSerialNumber"));
plist_array_append_item(keys, plist_new_string("FrontFacingCameraModuleSerialNumber"));
plist_array_append_item(keys, plist_new_string("MLBSerialNumber"));
plist_array_append_item(keys, plist_new_string("SysCfg"));
plist_array_append_item(keys, plist_new_string("marketing-name"));
if (diagnostics_relay_query_mobilegestalt(diagnostics_client, keys, &node) == DIAGNOSTICS_RELAY_E_SUCCESS)
{
if (node)
{
var = getListInfo(node);
varMap.insert("direct", var);
}
} else {
printf("ERROR: Unable to query mobilegestalt keys.\n");
}
plist_free(keys);
//摄像头 AppleH10CamIn
//rosaline-serial-num
//ambient-light-sensor-serial-num
//摄像头 AppleH10CamIn
for(int i = 1; i < 100; i++) // 其实最好的话,是根据产品类型那个值来确定这个数值,而不是这样轮询。。
{
QString entryName = QString("AppleH%1CamIn").arg(i);
var = getIoRegEntry(diagnostics_client, entryName, "");
if(var.isNull() == false)
{
varMap.insert("camera", var);
break;
}
}
//面板 AppleCLCD
var = getIoRegEntry(diagnostics_client, "AppleCLCD", "");
varMap.insert("panel", var);
//电池 AppleSmartBattery
var = getIoRegEntry(diagnostics_client, "AppleSmartBattery", "");
varMap.insert("battery", var);
mBattInfoXmlMap.insert(udid, getIoRegEntryXml(diagnostics_client, "AppleSmartBattery", ""));
diagnostics_relay_goodbye(diagnostics_client);
diagnostics_relay_client_free(diagnostics_client);
}
}
else
{
qDebug() << "ERROR: Could not start diagnostics service! line:" << __LINE__;
}
if (service)
{
lockdownd_service_descriptor_free(service);
service = NULL;
}
/* run query and output information */
qDebug() << "-------------";
qDebug() << "domain:" << domain << "key:" << key;
QVariant devVar;
if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS)
{
qDebug() << "00000" << format << domain << key;
if (node)
{
devVar = getListInfo(node);
plist_free(node);
node = NULL;
varMap.insert("base", devVar);
}
else
{
qDebug() << "error get node:";
}
}
devVar = QVariant();
//查询硬盘情况
domain = "com.apple.disk_usage.factory";
qDebug() << "domain:" << domain << "key:" << key;
if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS)
{
if (node)
{
devVar = getListInfo(node);
qDebug() << "-----------" << devVar.toMap().size();
plist_free(node);
node = NULL;
varMap.insert("disk", devVar);
}
else
{
qDebug() << "error get node:";
}
}
//获取出厂设置; 这个通用性比前面的 diagnostics_relay_query_mobilegestalt 要好。
// https://github.com/libimobiledevice/libimobiledevice/issues/1160
// iPhone 12 is empty, there is value < iPhone 12 ,do you know how to extra SysCfgData ?
domain = "com.apple.mobile.internal";
key = "SysCfgData";
qDebug() << "domain:" << domain << "key:" << key;
ldret = lockdownd_get_value(client, domain, key, &node);
if(ldret == LOCKDOWN_E_SUCCESS)
{
if (node)
{
devVar = getListInfo(node);
auto data = devVar.toByteArray();
qDebug() << "SysCfgData-----------" << data.length();
devVar = getDefaultDeviceInfo(data);
qDebug() << "-----------" << devVar.toMap().size();
varMap.insert("default", devVar);
plist_free(node);
node = NULL;
}
else
{
qDebug() << "error get node:" << domain << key;
}
}else{
fprintf(stderr, "ERROR: lockdownd_get_value fail: %s (%d)\n", lockdownd_strerror(ldret), ldret);
}
lockdownd_client_free(client);
idevice_free(device);
data = varMap;
return 0;
}