Obtenga CellID, MCC, MNC, LAC y Network en iOS 5.1

Necesito recuperar CellID, MCC, MNC, LAC y Network (GSM, 3G) de la torre de service celular actual en iOS 5.1 (iPhone 4S). Sé que esta información está disponible porque puedo verla en el modo FieldTest (accesible después de llamar **** 3001 # 12345 # ****). Supongo que será accesible a través de frameworks de iOS privados / no documentados.

En la pregunta iphone, verifique los valores de cellId / Lac, el autor indica que puedo get información de radio cellId, Lac, MNC, MCC en iOS , pero no se proporciona información sobre cómo hacerlo.

¿Alguien puede decirme cómo get esta información?

Sé de tres maneras cómo puedes hacerlo en iOS 5.x – 7.x. Todos ellos usan API privadas de CoreTelephony.framework. Admite tanto GSM como UMTS.

1) Uso del monitor celular

 struct CTResult { int flag; int a; }; extern CFStringRef const kCTCellMonitorCellType; extern CFStringRef const kCTCellMonitorCellTypeServing; extern CFStringRef const kCTCellMonitorCellTypeNeighbor; extern CFStringRef const kCTCellMonitorCellId; extern CFStringRef const kCTCellMonitorLAC; extern CFStringRef const kCTCellMonitorMCC; extern CFStringRef const kCTCellMonitorMNC; extern CFStringRef const kCTCellMonitorUpdateNotification; id _CTServerConnectionCreate(CFAllocatorRef, void*, int*); void _CTServerConnectionAddToRunLoop(id, CFRunLoopRef, CFStringRef); #ifdef __LP64__ void _CTServerConnectionRegisterForNotification(id, CFStringRef); void _CTServerConnectionCellMonitorStart(id); void _CTServerConnectionCellMonitorStop(id); void _CTServerConnectionCellMonitorCopyCellInfo(id, void*, CFArrayRef*); #else void _CTServerConnectionRegisterForNotification(struct CTResult*, id, CFStringRef); #define _CTServerConnectionRegisterForNotification(connection, notification) { struct CTResult res; _CTServerConnectionRegisterForNotification(&res, connection, notification); } void _CTServerConnectionCellMonitorStart(struct CTResult*, id); #define _CTServerConnectionCellMonitorStart(connection) { struct CTResult res; _CTServerConnectionCellMonitorStart(&res, connection); } void _CTServerConnectionCellMonitorStop(struct CTResult*, id); #define _CTServerConnectionCellMonitorStop(connection) { struct CTResult res; _CTServerConnectionCellMonitorStop(&res, connection); } void _CTServerConnectionCellMonitorCopyCellInfo(struct CTResult*, id, void*, CFArrayRef*); #define _CTServerConnectionCellMonitorCopyCellInfo(connection, tmp, cells) { struct CTResult res; _CTServerConnectionCellMonitorCopyCellInfo(&res, connection, tmp, cells); } #endif 

 id CTConnection = _CTServerConnectionCreate(NULL, CellMonitorCallback, NULL); _CTServerConnectionAddToRunLoop(CTConnection, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); _CTServerConnectionRegisterForNotification(CTConnection, kCTCellMonitorUpdateNotification); _CTServerConnectionCellMonitorStart(CTConnection); int CellMonitorCallback(id connection, CFStringRef string, CFDictionaryRef dictionary, void *data) { int tmp = 0; CFArrayRef cells = NULL; _CTServerConnectionCellMonitorCopyCellInfo(connection, (void*)&tmp, &cells); if (cells == NULL) { return 0; } for (NSDictionary* cell in (NSArray*)cells) { int LAC, CID, MCC, MNC; if ([cell[(NSString*)kCTCellMonitorCellType] isEqualToString:(NSString*)kCTCellMonitorCellTypeServing]) { LAC = [cell[(NSString*)kCTCellMonitorLAC] intValue]; CID = [cell[(NSString*)kCTCellMonitorCellId] intValue]; MCC = [cell[(NSString*)kCTCellMonitorMCC] intValue]; MNC = [cell[(NSString*)kCTCellMonitorMNC] intValue]; } else if ([cell[(NSString*)kCTCellMonitorCellType] isEqualToString:(NSString*)kCTCellMonitorCellTypeNeighbor]) { } } CFRelease(cells); return 0; } 

2) usando CTTelephonyCenter

kCTRegistrationCellChangedNotification se envía cada vez que se cambia la torre de la celda de service actual.

 extern CFStringRef const kCTRegistrationCellChangedNotification; extern CFStringRef const kCTRegistrationGsmLac; extern CFStringRef const kCTRegistrationLac; extern CFStringRef const kCTRegistrationGsmCellId; extern CFStringRef const kCTRegistrationCellId; CFStringRef CTSIMSupportCopyMobileSubscriberCountryCode(CFAllocatorRef); CFStringRef CTSIMSupportCopyMobileSubscriberNetworkCode(CFAllocatorRef); id CTTelephonyCenterGetDefault(); void CTTelephonyCenterAddObserver(id, void, CFNotificationCallback, CFStringRef, void, CFNotificationSuspensionBehavior); 

 CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault(), NULL, callback, NULL, NULL, CFNotificationSuspensionBehaviorHold); void callback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { NSString* notification = (NSString*)name; NSDictionary *cellInfo = (NSDictionary*)userInfo; if ([notification isEqualToString:(NSString*)kCTRegistrationCellChangedNotification]) { int LAC, CID, MCC, MNC; if (cellInfo[(NSString*)kCTRegistrationGsmLac]) { LAC = [cellInfo[(NSString*)kCTRegistrationGsmLac] intValue]; } else if (data[(NSString*)kCTRegistrationLac]) { LAC = [cellInfo[(NSString*)kCTRegistrationLac] intValue]; } if (cellInfo[(NSString*)kCTRegistrationGsmCellId]) { CID = [cellInfo[(NSString*)kCTRegistrationGsmCellId] intValue]; } else if (cellInfo[(NSString*)kCTRegistrationCellId]) { CID = [cellInfo[(NSString*)kCTRegistrationCellId] intValue]; } MCC = [[(NSString*)CTSIMSupportCopyMobileSubscriberCountryCode(NULL) autorelease] intValue]; MNC = [[(NSString*)CTSIMSupportCopyMobileSubscriberNetworkCode(NULL) autorelease] intValue]; } } 

3) Esto devuelve la torre celular actual de service

 struct CTResult { int flag; int a; }; id _CTServerConnectionCreate(CFAllocatorRef, void*, int*); #ifdef __LP64__ void _CTServerConnectionGetLocationAreaCode(id, int*); void _CTServerConnectionGetCellID(id, int*); #else void _CTServerConnectionGetLocationAreaCode(struct CTResult*, id, int*); #define _CTServerConnectionGetLocationAreaCode(connection, LAC) { struct CTResult res; _CTServerConnectionGetLocationAreaCode(&res, connection, LAC); } void _CTServerConnectionGetCellID(struct CTResult*, id, int*); #define _CTServerConnectionGetCellID(connection, CID) { struct CTResult res; _CTServerConnectionGetCellID(&res, connection, CID); } #endif 

 int CID, LAC, MCC, MNC; id CTConnection = _CTServerConnectionCreate(NULL, NULL, NULL); _CTServerConnectionGetCellID(CTConnection, &CID); _CTServerConnectionGetLocationAreaCode(CTConnection, &LAC); MCC = [[(NSString*)CTSIMSupportCopyMobileSubscriberCountryCode(NULL) autorelease] intValue]; MNC = [[(NSString*)CTSIMSupportCopyMobileSubscriberNetworkCode(NULL) autorelease] intValue]; 

ACTUALIZAR

En ARM64 (iPhone 5S) hay un problema con todas las funciones de CoreTelephony que aceptan el argumento struct CTResult . Al parecer, la versión de CoreTelephony de 64 bits exporta estas funciones sin el argumento struct CTResult . Debido a eso, obtendrás un error en ARM64 si llamas a estas funciones como lo hiciste en el pasado: los arguments serán incorrectos. Actualicé las declaraciones de function para que funcionen en architectures ARM de 32 y 64 bits. Lo probé y funciona tanto en iPhone 4S como iPhone 5S.

Esto solo se aplica a ARM64. Si construye su proyecto para la architecture ARM de 32 bits, entonces no existe tal problema. Su aplicación usará la versión de CoreTelephony de 32 bits que espera el argumento struct CTResult .

8.3 ACTUALIZACIÓN

A partir del iOS 8.3, todas las soluciones anteriores requieren autorización para trabajar

 <key>com.apple.CommCenter.fine-grained</key> <array> <string>spi</string> </array> 

No solo está protegido el monitor de celda, sino que parece que todas las notifications de CoreTelephony ahora requieren el derecho a trabajar. Por ejemplo, kCTMessageReceivedNotification también se vio afectada.

suscriberCellularProvider es un método de object (vs método de class).

Puedes echar un vistazo a cómo usarlo aquí: determina el país del usuario de iPhone

Creo que CTCarrier tiene MCC y MNC.

Puede verificar el tipo de networking usando el código de esta pregunta: Cómo verificar si el iPhone es compatible con CDMA o GSM

Y mire esta pregunta para CellID: CTServerConnectionGetCellID telefonía básica de rutina

El código que figura a continuación es cómo insert el código para trabajar con el código en iOS 8.3. A partir del iOS 8.3, todas las soluciones anteriores requieren autorización para trabajar

 <key>com.apple.CommCenter.fine-grained</key> <array> <string>spi</string> </array> 

De hecho, se dice que el código mencionado anteriormente se puede ejecutar para get la lac y la celda en ios 8.3 y superiores. Pero realmente no sé cómo insert lo anterior en un teléfono jailbroken. ¿Alguien podría dar información detallada?