Enable/Disable Wifi on non-jailbroken iOS device - ios

This I needed for my internal app. I want to toggle wifi on ios device. Any framework is available.
I tried following code, but it provides me no help. This doesn't change my wifi settings.
{
Class BluetoothManager = objc_getClass("BluetoothManager");
id btCont = [BluetoothManager sharedInstance];
[self performSelector:#selector(toggle:) withObject:btCont afterDelay:0.1f] ;
}
- (void)toggle:(id)btCont
{
BOOL currentState = [btCont enabled] ;
[btCont setEnabled:!currentState] ;
[btCont setPowered:!currentState] ;
exit( EXIT_SUCCESS ) ;
}

From Application
notify_post("com.yourcompany.yourapp.yournotification");
From Dylib
#import <objc/runtime.h>
#import <SpringBoard/SBWiFiManager.h>
HOOK(SpringBoard, applicationDidFinishLaunching$, void, id app) {
//Listen for events via DARWIN NOTIFICATION CENTER
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL,
&NotificationReceivedCallback, CFSTR("com.yourcompany.yourapp.yournotification"), NULL,
CFNotificationSuspensionBehaviorCoalesce);
}
//THIS IS WHERE THE MAGIC HAPPENS
static void NotificationReceivedCallback(CFNotificationCenterRef center,
void *observer, CFStringRef name,
const void *object, CFDictionaryRef
userInfo)
{
[[objc_getClass("SBWiFiManager") sharedInstance] setWiFiEnabled:NO];
}
Note:
if you enounter any error on using Hook method you can refer this link it demonstrates how to hook init method found in SpringBoard to show a alert message when starting up the phone.
Warning:
You can not use this for appstore apps since private api is used.
Reference
Attribtuion
Hope this helps.

You're not going to be able to. iOS limits just how much third-party apps can interact with the underlying hardware. All applications written with the public SDK are sandboxed.
As 7KV7 says in their answer here:
They only have access to the properties and data which
Apple deems feasible to use within that sandbox. I am afraid Wi-fi
doesn't come in the list.

Related

Remote Audio not connecting: iOS, PJSIP 2.6, CallKit, PJSUA2

I am updating an existing iOS VOIP application to use CallKit with PJSIP 2.6 and PJSUA2.
After some effort, the CallKit implementation seems to be working as expected. Incoming calls can be accepted or declined, and if accepted, will be connected and controlled with an in-app active call view controller.
The audio, however, does not appear to be properly connected at the pjsip end. There is no audio coming in from, or going out to the remote caller. The microphone audio appears to be routed back to the iPhone speaker.
The SIP audio ports should be connecting in callback function onCallMediaState:
virtual void onCallMediaState(OnCallMediaStateParam &prm) {
CallInfo ci = getInfo();
AudioMedia* audio_media = 0;
for (unsigned i = 0; i < ci.media.size(); i++) {
if (ci.media[i].type==PJMEDIA_TYPE_AUDIO && ( ci.media[i].status == PJSUA_CALL_MEDIA_ACTIVE ||
ci.media[i].status ==PJSUA_CALL_MEDIA_REMOTE_HOLD)) {
try {
audio_media = static_cast<AudioMedia*>(getMedia(i));
if(audio_media != 0)
{
Endpoint::instance().audDevManager().getCaptureDevMedia().startTransmit(*audio_media);
audio_media->startTransmit(Endpoint::instance().audDevManager().getPlaybackDevMedia());
}
} catch (std::exception ex) {
continue;
}
}
}
}
As described in Ticket#1941 at:
https://trac.pjsip.org/repos/ticket/1941:
I set the audio devices using:
ep->audDevManager().setNullDev();
immediately after the initialization of the Endpoint class (ep->libInit(epConfig);), and then:
I attempt to set the devices using pjsua_set_snd_dev() in CXProvider’s didActivate function, like this:
-(void) setSipSoundDevices {
pj_status_t status;
int captDev, playDev;
pjsua_get_snd_dev(&captDev, &playDev);
Endpoint::instance().audDevManager().setPlaybackDev(playDev);
Endpoint::instance().audDevManager().setCaptureDev(captDev);
}
pjsua_get_snd_dev(&captDev, &playDev) returns -99, -99 and the audio does not connect.
My question is this. How can I properly hook up the remote audio sources or ports, on an incoming call using PJSIP 2.6 and CallKit?
Might 2.5.5 work better in this regard?
Any insights are appreciated.
By and by I got the incoming call audio working properly. The crux of the matter was that even though the documentation from both Apple and SIP say that the audio has to be handled on the iOS end, you still have to set the SIP audio devices in the SIP layer in the provider delegate 'didActivate' and 'didDeactivate' functions. Because I use the PJSUA C++ layer, I had to drill down through the objc-c++ bridging layer to provide this functionality. ie.
-(void) activateSipSoundDevices {
pj_status_t status = pjsua_set_snd_dev(0, 0);
}
-(void) deactivateSipSoundDevices {
pj_status_t status = pjsua_set_null_snd_dev();
}
When initializing the SIP Account, be sure to set the null sound devices like:
ep->audDevManager().setNullDev();
Hope this helps.

Use Bloothtooth LE while app is in background

I am building an iOS app with Xamarin, with this BLE plugin:
https://github.com/aritchie/bluetoothle
I'm just broadcasting a UUID via BLE, and it works. Here is my code:
var data = new Plugin.BluetoothLE.Server.AdvertisementData
{
LocalName = "MyServer",
};
data.ServiceUuids.Add(new Guid("MY_UUID_HERE"));
await this.server.Start(data);
The only problem is that it stops broadcasting once I put the app in the background. And resumes again when I open the app again.
How can I let it continue to broadcast once it's in the background? I read the documentation here:
https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html
And it says that I have to use the CBCentralManager class to obtain the preservation and restoration feature (so I can keep broadcasting the UUID at all times), but I'm having a hard time translating this to Xamarin/C#.
EDIT
After researching some more, I read that I need to create an instance of CBCentralManager and implement WillRestoreState in the delegate. I did this in the AppDelegate:
[Register("AppDelegate")]
public class AppDelegate : MvxApplicationDelegate, ICBCentralManagerDelegate
{
private IGattServer server = CrossBleAdapter.Current.CreateGattServer();
private CBCentralManager cbCentralManager;
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// irrelevant code...
this.Ble();
return true;
}
private async Task Ble()
{
try
{
await Task.Delay(5000); // wait for it to finish initializing so I can access BLE (it crashes otherwise)
var options = new CBCentralInitOptions();
options.RestoreIdentifier = "myRestoreIndentifier";
this.cbCentralManager = new CBCentralManager(this,null,options);
var data = new Plugin.BluetoothLE.Server.AdvertisementData
{
LocalName = "MyServer",
};
data.ServiceUuids.Add(new Guid("MY_UUID_HERE"));
await this.server.Start(data);
}
catch (Exception e)
{
}
}
public void UpdatedState(CBCentralManager central)
{
//throw new NotImplementedException();
}
[Export("centralManager:willRestoreState:")]
public void WillRestoreState(CBCentralManager central, NSDictionary dict)
{
//never gets called
}
But it didn't make a difference for me. And the WillRestoreState method never gets called... I don't mind using a different plugin/library if I have to at this point...
EDIT 2
I just realized that the app is still broadcasting while it is in the background, I just don't see the service UUID anymore (in the web portal of the beacon that I'm testing with), I only see the phone's identifier.
After doing tons of research, I found that it is simply an iOS restriction - you can not broadcast the UUID of a BLE service while your app is in the background. Background work is very restrictive in iOS.
EDIT to include Paulw11 comment (which is true):
You can advertise a service, but it is advertised in a way that only another iOS device that is specifically scanning for that service UUID can see.
Although you can not broadcast the UUID of a BLE service while your iOS app is in the background, for anyone trying to do something similar, you should look into iBeacon. It's Apple's protocol for letting iOS apps do bluetooth stuff while it's in the background.

how to get iOS app notified whenever user switches between wifi networks [duplicate]

This is for a tweak, so the target is jailbroken devices, and not the app store.
I have tried hooking different methods in the SBWiFiManager but they either are called when the wifi strength changes (so continuously) or after quite delay after the network has changed.
Is there any other way to get a notification (or another method to hook) went the wifi network changes?
I know you can get the current SSID with public APIs now, but I need to be told when it changes.
One way to do this is to listen for the com.apple.system.config.network_change event from the Core Foundation Darwin notification center.
Register for the event:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
NULL, // observer
onNotifyCallback, // callback
CFSTR("com.apple.system.config.network_change"), // event name
NULL, // object
CFNotificationSuspensionBehaviorDeliverImmediately);
Here's a sample callback:
static void onNotifyCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
NSString* notifyName = (NSString*)name;
// this check should really only be necessary if you reuse this one callback method
// for multiple Darwin notification events
if ([notifyName isEqualToString:#"com.apple.system.config.network_change"]) {
// use the Captive Network API to get more information at this point
// https://stackoverflow.com/a/4714842/119114
} else {
NSLog(#"intercepted %#", notifyName);
}
}
See my link to another answer on how to use the Captive Network API to get the current SSID, for example.
Note that although the phone I tested this on is jailbroken (iOS 6.1), I don't think this requires jailbreaking to work correctly. It certainly doesn't require the app being installed outside the normal sandbox area (/var/mobile/Applications/*).
P.S. I haven't tested this exhaustively enough to know whether this event gives any false positives (based on your definition of a network change). However, it's simple enough just to store some state variable, equal to the last network's SSID, and compare that to the current one, whenever this event comes in.
SWIFT 4.1 version
I've extend my Reachability class with this functions:
let notificationName = "com.apple.system.config.network_change"
func onNetworkChange(_ name : String) {
if (name == notificationName) {
// Do your stuff
print("Network was changed")
}
}
func registerObserver() {
let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer,
{ (nc, observer, name, _, _) -> Swift.Void in
if let observer = observer, let name = name {
let instance = Unmanaged<Reachability>.fromOpaque(observer).takeUnretainedValue()
instance.onNetworkChange(name.rawValue as String)
} },
notificationName as CFString, nil, .deliverImmediately)
}
func removeObserver() {
let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer, nil, nil)
}
Register observer on init and remove on deinit.
Unfortunately there is no additional info about what exactly was changed but we take a chance to test current SSID for example.
Hope this will helpful for somebody)

Xamarin.iOS CoreBluetooth/External Accesory issue

I've looking here on Forums, on the monotouch samples GIT hub, and never found a really functional sample to use CoreBluetooth in order to achieve the following:
1.Check if is there a device that match a criteria(by name or some identifier of the device) paired and connected
2.If paired but not connected, try connect to it
3.If connection fails, then show a list of the bluetooth devices that matches the criterias on topic 1 so the user can select and connect to it
Note: The device I'm trying to connect uses SPP but is Apple MFi certified. It is a credit card reader over bluetooth and some of then even implement ExternalAccessory protocols
The CoreBluetooth samples page is empty http://developer.xamarin.com/samples/ios/CoreBluetooth/
I've trying this pretty simple sample that never get the events called after the scan:
public static class BTHelper
{
private static CBCentralManager manager;
private static CBUUID UUID;
static BTHelper()
{
manager =
manager.DiscoveredPeripheral += OnDiscovery;
manager.ConnectedPeripheral += OnConnected;
manager.DisconnectedPeripheral += OnDisconnected;
UUID = CBUUID.FromString("00001101-0000-1000-8000-00805F9B34FB");
}
public static void CheckBluetooth()
{
manager.ScanForPeripherals(new[] { UUID });
}
static void OnDisconnected(object sender, CBPeripheralErrorEventArgs e)
{
Console.WriteLine("Disconnected - " + e.Peripheral.Name);
}
static void OnConnected(object sender, CBPeripheralEventArgs e)
{
Console.WriteLine("Connected - " + e.Peripheral.Name);
}
static void OnDiscovery(object sender, CBDiscoveredPeripheralEventArgs e)
{
Console.WriteLine("Found - " + e.Peripheral.Name);
}
}
Can anyone help? I've being really tired of googling and looking of many questions on SO with no real answer.
#XamarinTeam, you guys should provide a sample on how to use it... We are lost without reference...
Thank, really appreciate any help...
Gutemberg
It seems like you are looking at wrong documents.Core Bluetooth only allows you to communicate with Bluetooth Low Energy (BLE) devices using the GATT profile. you can not scan SPP device with corebluetooth.
For your MFI device, you need to check External Accessory framework , It allows communication with 'legacy' Bluetooth devices using profiles such as the Serial Port Protocol (SPP).
To answer your question:
: 1.Check if is there a device that match a criteria(by name or some identifier of the device) paired and connected
You can use showBluetoothAccessoryPicker function of EAAccessoryManager to get list of Available devices, read more here
2.If paired but not connected, try connect to it
There is not any documented way to check for this. You can not initiate connect from app without showBluetoothAccessoryPicker . You can monitor for
EAAccessoryDidConnect notification. if this method is not called, and showbluetoothaccessorypicker 's complition get called, your device is not connected.
3.If connection fails, then show a list of the bluetooth devices that matches the criterias on topic 1 so the user can select and connect to it
1)
After completion of showbluetoothaccessorypicker You can check in ConnectedAccessories . If its not avaiable, call showbluetoothaccessorypicker to display list of accessories.
Sample code for using External Accessory framework in your code
EAAccessoryManager manager= EAAccessoryManager.SharedAccessoryManager;
var allaccessorries= manager.ConnectedAccessories;
foreach(var accessory in allaccessorries)
{
yourlable.Text = "find accessory";
Console.WriteLine(accessory.ToString());
Console.WriteLine(accessory.Name);
var protocol = "com.Yourprotocol.name";
if(accessory.ProtocolStrings.Where(s => s == protocol).Any())
{
yourlable.Text = "Accessory found";
//start session
var session = new EASession(accessory, protocol);
var outputStream = session.OutputStream;
outputStream.Delegate = new MyOutputStreamDelegate(yourlable);
outputStream.Schedule(NSRunLoop.Current, "kCFRunLoopDefaultMode");
outputStream.Open();
}
}
and
public class MyOutputStreamDelegate : NSStreamDelegate
{
UILabel label;
bool hasWritten = false;
public MyOutputStreamDelegate(UILabel label)
{
this.label = label;
}
public override void HandleEvent(NSStream theStream, NSStreamEvent streamEvent)
{
//write code to handle stream.
}
}
There is not any perticular demo for using Exeternal Accessory framework,
but You can check this sample code for understanding how it works.:
Whole Project
AccessoryBrowser class

Intercepting phone call - iPhone (correct method to hook in CoreTelephony)

I am new to the jailbreak tweak development scene. I am trying to figure out the appropriate method to 'hook' so I can intercept an incoming call (and then run some code).
I have dumped the header files of CoreTelephony framework however no methods seem obvious to hook. I have tried:
- (void)broadcastCallStateChangesIfNeededWithFailureLogMessage:(id)arg1;
- (BOOL)setUpServerConnection;
but neither have worked. By worked I mean - get called when the iPhone receives a call.
Any pointers as to the appropriate method to hook? Thanks :)
Note:
This is going to be a jailbreak tweak using private APIs so it won't be submitted to the App Store.
I didn't test your code, but I think your problem might be that you need to use the Core Telephony notification center to register for that event (not what you had in the code in your comment). Something like this:
// register for all Core Telephony notifications
id ct = CTTelephonyCenterGetDefault();
CTTelephonyCenterAddObserver(ct, // center
NULL, // observer
telephonyEventCallback, // callback
NULL, // event name (or all)
NULL, // object
CFNotificationSuspensionBehaviorDeliverImmediately);
and your callback function is
static void telephonyEventCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
NSString *notifyname = (NSString*)name;
if ([notifyname isEqualToString:#"kCTCallIdentificationChangeNotification"])
{
NSDictionary* info = (NSDictionary*)userInfo;
CTCall* call = (CTCall*)[info objectForKey:#"kCTCall"];
NSString* caller = CTCallCopyAddress(NULL, call);
if (call.callState == CTCallStateDisconnected)
{
NSLog(#"Call has been disconnected");
}
else if (call.callState == CTCallStateConnected)
{
NSLog(#"Call has just been connected");
}
else if (call.callState == CTCallStateIncoming)
{
NSLog(#"Call is incoming");
}
else if (call.callState == CTCallStateDialing)
{
NSLog(#"Call is Dialing");
}
else
{
NSLog(#"None of the conditions");
}
}
}
I offer another technique in this similar question here. Also, note my comment in that question about not getting the notifications in a UIApplication that has been put into the background.
Update: see cud_programmer's comment below about using kCTCallStatus on iOS 6 instead of kCTCall.
Is it possible?
Yes.
Would a regular average person with no background in computer engineering or knowhow of how cell towers work be capable of something like this?
No.
Technically you can buy router looking thing to do this which aren’t cheap, are illegal and cellphone companies can actually track them down since it interferes with the network. So other than government agencies or international spies i don’t think you have anything to worry about. But if the government is exactly what you’re worried about well I’m sorry to tell you they’ve been doing a lot more then intercepting just phones

Resources