How to know if the network state is WiFi hotspot on iOS - ios

Now I can just recognize WiFi/2G/3G/4G, but when the state is WiFi hotspot, AFNetworkReachabilityManager or Reachability also recognize the state as WiFi. Please help me to achieve this requirement, thanks a lot.

I had found the right way:
- (void)startMonitorWifiChange {
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
NULL,
&onNotifyCallback,
CFSTR("com.apple.system.config.network_change"),
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
}
static void onNotifyCallback(CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo) {
if (CFStringCompare(name, CFSTR("com.apple.system.config.network_change"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
//TODO when wifi changed
[[BaiduLocationManager sharedManager].baiduLocationManager requestNetworkState];
}
else {
NBLog(#"intercepted %#", name);
}
}
- (void)stopMonitorWifiChange {
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(),
NULL,
CFSTR("com.apple.system.config.network_change"),
NULL);
}

Related

How to hook Apple's `os_log_with_type` method in Objective-C

I want to hook "React Native" RCTLog logs method _RCTLogJavaScriptInternal , The source codes is:
void _RCTLogJavaScriptInternal(RCTLogLevel level, NSString *message)
{
RCTLogFunction logFunction = RCTGetLocalLogFunction();
BOOL log = RCT_DEBUG || (logFunction != nil);
if (log && level >= RCTGetLogThreshold()) {
if (logFunction) {
logFunction(level, RCTLogSourceJavaScript, nil, nil, message);
}
}
}
RCTLogFunction RCTDefaultLogFunction =
^(RCTLogLevel level,
RCTLogSource source,
__unused NSString *fileName,
__unused NSNumber *lineNumber,
NSString *message) {
os_log_with_type(RCTLogForLogSource(source), RCTLogTypeForLogLevel(level), "%{public}s", message.UTF8String);
};
So if I just hook Apple's os_log_with_type, I will get the RCTLog logs.
This is my codes, but not working. Please help me. Thanks!!!!
#import <os/log.h>
#import "fishhook.h"
static void (*original_oslog)((os_log_t log, os_log_type_t type, const char *format, ...));
void hook_oslog(os_log_t log, os_log_type_t type, const char *format, ...) {
NSLog(#"hook success!");
}
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
struct rebinding oslog_rebinding = { "os_log_with_type", hook_oslog, (void *)&original_oslog };
rebind_symbols((struct rebinding[1]){oslog_rebinding}, 1);
});
}
Final, I found solution. Not need to hook, Related API have been provided by React Native already.
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
NSLog(#"%#", message);
});

PJSip : Not able to unhold the hold call

Getting this error while unholding a call using pjsip.
Unable to create re-INVITE: Invalid operation (PJ_EINVALIDOP)
[status=70013]
Error hanging up call: Invalid operation (PJ_EINVALIDOP) [status=70013]
Using this code for untold
pj_status_t pj_wrapper_unhold_call(pjsua_call_id call_id, char deviceId, char groupId, char *token) {
pj_status_t status;
if (!pj_wrapper_initialized) {
return PJ_EGONE;
}
status = pjsua_call_reinvite(call_id, PJSUA_CALL_UNHOLD, NULL);
if (status != PJ_SUCCESS) {
pj_wrapper_show_error("Error hanging up call", status);
}
return status;
}

iOS CFSocket crash on empty UDP packet

I am using a CFSocket configured for UDP to send data through wifi. The problem is that when I receive an empty UDP packet, the wifi suddenly stops working. I cant receive or send wnything anymore after that. Does anyone know what seems to be the problem? Here is my configuration and callback code:
void socketCallback(CFSocketRef cfSocket, CFSocketCallBackType type, CFDataRef address, const void *data, void *userInfo)
{
NSData * inputData = (__bridge NSData*)data;
NSUInteger inputDataCapacity = inputData.length * 2;
if(inputDataCapacity > minimalFrameSize*2){
//DO STH
}
}
-(void) initNetworkCommunication
{
CFSocketContext socketContext = {0, (__bridge void *)(self), NULL, NULL, NULL};
_cfSocket = CFSocketCreate(kCFAllocatorDefault, AF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketAcceptCallBack | kCFSocketDataCallBack, (CFSocketCallBack)socketCallback, &socketContext);
if ( _cfSocket == NULL) {
// NSLog(#"CfSocketCreate failed");
}
else {
if( _cfSocket ) {
_addrData = [Utils createIpAddressDataRef:COMM_INT_LISTENER_ADDR];
int flag = 1;
CFSocketNativeHandle socket_handle = (CFSocketNativeHandle)CFSocketGetNative(_cfSocket);
setsockopt(socket_handle, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag));
//set address of the socket to listen to
CFSocketSetAddress (_cfSocket, _addrData);
_cfSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _cfSocket, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), _cfSource, kCFRunLoopDefaultMode);
CFRelease(_cfSource);
CFRelease(_cfSocket);
}
}
}
And sometimes after the wifi "crash" happens, I get an "EXC_BAD_ACCESS" when using CFSocketSendData.

How to communicate between applications in iOS?

Before we can use CFMessagePort, but now it's invalid for iOS7 and above, is there any replaced methods? I tried CFMessagePort when hooking the constructor of UIApplication in the jailbreak environment, but in most of the apps, it can't CFMessagePortCreateLocal successfully, it just return NULL.Am I wrong somewhere?
static void setupUIApplicationMessagePort()
{
NSString *identifier = #"com.foo.foo.UIApplication";
CFMessagePortRef local = CFMessagePortCreateLocal(NULL, (__bridge CFStringRef)identifier, callBackForUIApplication, NULL, NULL);
if (local) {
NSLog(#"local OK: %#", local);
CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(NULL, local, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
rocketbootstrap_cfmessageportexposelocal(local);
} else {
NSLog(#"local is NULL"); // in most of the apps it returns NULL
}
}
%ctor {
if(%c(UIApplication)) {
setupUIApplicationMessagePort();
}
}
try CFNotificationCenter using CFNotificationCenterGetDarwinNotifyCenter
#include <CoreFoundation/CFNotificationCenter.h>
/* This function will be called whatever a notification posted with the specified name */
void NotificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){
}
void addObserver(){
CFStringRef name = CFSTR("NotificationName");
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),&NotificationCallback,name,NULL,CFNotificationSuspensionBehaviorDeliverImmediately);
}
This will listen to notifications named NotificationName
To post a notification
void postNotification(){
CFStringRef name = CFSTR("NotificationName");
/* You have to create the userInfo dictionary and add all the keys to it */
CFDictionaryRef userInfo;
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), name, NULL, userInfo, true);
}

Knowing when headphones are connected to the 3.5 mm jack works only if they weren't connected before the app started

I got this code to tell if the headphones are connected or not:
This in viewDidLoad:
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioSessionPropertyListener, nil);
This function:
void audioSessionPropertyListener(void* inClientData, AudioSessionPropertyID inID,
UInt32 inDataSize, const void* inData) {
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
// Determines the reason for the route change, to ensure that it is not
// because of a category change.
CFDictionaryRef routeChangeDictionary = inData;
CFNumberRef routeChangeReasonRef = CFDictionaryGetValue (routeChangeDictionary,CFSTR (kAudioSession_AudioRouteChangeKey_Reason));
SInt32 routeChangeReason;
CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);
// "Old device unavailable" indicates that a headset was unplugged, or that the
// device was removed from a dock connector that supports audio output.
if (routeChangeReason != kAudioSessionRouteChangeReason_OldDeviceUnavailable) {
[[Cubic_01AppDelegate sharedInstance] setDongleIsDisonnected];
}
if (!isHeadsetPluggedIn())
{
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
}
else
{
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
}
}
and this function:
BOOL isHeadsetPluggedIn() {
UInt32 routeSize = sizeof (CFStringRef);
CFStringRef route;
OSStatus error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute,
&routeSize,
&route
);
NSLog(#"%#", route);
BOOL isPluggedIn = !error && (route != NULL) && ([(NSString*)route rangeOfString:#"Head"].location != NSNotFound);
if (isPluggedIn) {
[[Cubic_01AppDelegate sharedInstance] setDongleIsConnected];
} else {
[[Cubic_01AppDelegate sharedInstance] setDongleIsDisonnected];
}
return (isPluggedIn);
}
Can anyone please help with telling me why the audioSessionPropertyListener function isn't invoked when the headphones are already connected before the app starts?
You need to provide your check on load/startup of the application. Basically you should be able to call:
- (void) viewDidLoad
{
isHeadsetPluggedIn()
}
The property listener has not been set if you haven't started your application before connecting the headphones. Note that the property listener is checking for changes only.
So you will need to provide your check on load/startup of the application. You can get the AudioSession properties directly without using a listener and thus parse. And that is exactly what you do in isHeadsetPluggedIn() as you call:
OSStatus error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute,
&routeSize,
&route);
This method can be called in objective c and c++ functions alike. It can be called anywhere to get any property of the AudioSession after it has been initialized.

Resources