1. 程式人生 > >iPhone/iOS獲得基站資訊[整理]

iPhone/iOS獲得基站資訊[整理]

//CoreTelephony.m
#import "CoreTelephony.h"
#include <dlfcn.h>
#import <UIKit/UIKit.h>
#include <stdio.h>
#include <stdlib.h>

CFMachPortRef port;
struct CTServerConnection *sc=NULL;
//struct CTServerConnection scc;
struct CellInfo cellinfo;
int b;
int t1;

@implementation CoreTelephony

int callback(
CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    printf("Callback calledn");
    return 0;
}

- (void) getCellInfo
{
    int cellcount;
    char* sdk_path = "/System/Library/Frameworks/CoreTelephony.framework/CoreTelephony";

    // void * dlopen( const char * pathname, int mode );

    // 功能:以指定模式開啟指定的動態連線庫檔案,並返回一個控制代碼給呼叫程序。 開啟錯誤返回NULL,成功,返回庫引用
    // RTLD_LAZY 暫緩決定,等有需要時再解出符號。這個引數使得未解析的symbol將在使用時去解析
    int* handle =dlopen(sdk_path, RTLD_LAZY);
    if (handle == NULL) {
        return;
    }

    // void* dlsym(void* handle,const char* symbol) 該函式在<dlfcn.h>檔案中。將庫中的一個函式繫結到預定義的函式地址(即獲取到函式的指標)。handle是由dlopen開啟動態連結庫後返回的指標,symbol就是要求獲取的函式的名稱,函式返回值是void*,指向函式的地址,供呼叫使用。

    struct CTServerConnection * (*CTServerConnectionCreate)() = dlsym(handle, "_CTServerConnectionCreate");
    sc=CTServerConnectionCreate(kCFAllocatorDefault, callback, &t1);

//    int (*CTServerConnectionGetPort)() = dlsym(handle, "_CTServerConnectionGetPort");
//    port=CFMachPortCreateWithPort(kCFAllocatorDefault, _CTServerConnectionGetPort(sc), NULL, NULL, NULL);

    void (*CTServerConnectionCellMonitorStart)() = dlsym(handle, "_CTServerConnectionCellMonitorStart");
    CTServerConnectionCellMonitorStart(&t1,sc);

    int* (*CTServerConnectionCellMonitorGetCellCount)() = dlsym(handle, "_CTServerConnectionCellMonitorGetCellCount");
    CTServerConnectionCellMonitorGetCellCount(&t1,sc,&cellcount);
    NSLog(@"cellcount:%d",cellcount);

    void (*CTServerConnectionCellMonitorGetCellInfo)() = dlsym(handle, "_CTServerConnectionCellMonitorGetCellInfo");

    for(int b=0;b<cellcount;b++)
    {
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

        memset(&cellinfo, 0, sizeof(struct CellInfo));
        int ts = 0;

        /** 這個方法的問題出現在這裡,3.0以前的版本是4個引數,執行後會崩潰,後來發現新版本中是5個引數,不過獲取的結果不理想,只獲取了5個結果:MNC,MCC,LAC,CELLID,PXLEVEL,其他4項四項返回-1*/
        CTServerConnectionCellMonitorGetCellInfo(&t1, sc, b, &ts, &cellinfo);

        printf("Cell Site: %d, MNC: %d, ",b,cellinfo.servingmnc);
        printf("LAC: %d, Cell ID: %d, Station: %d, ",cellinfo.location, cellinfo.cellid, cellinfo.station);
        printf("Freq: %d, RxLevel: %d, ", cellinfo.freq, cellinfo.rxlevel);
        printf("C1: %d, C2: %dn", cellinfo.c1, cellinfo.c2);

        [pool release];
        pool = nil;
    }

    // 使用dlclose()來解除安裝開啟的庫
    dlclose(handle);
}