diff --git a/CCModule/MQTTModule.h b/CCModule/MQTTModule.h new file mode 100644 index 0000000..6538e5b --- /dev/null +++ b/CCModule/MQTTModule.h @@ -0,0 +1,8 @@ +#import + +@interface MQTTModule : CCUIToggleModule +{ + BOOL _selected; +} + +@end diff --git a/CCModule/MQTTModule.m b/CCModule/MQTTModule.m new file mode 100644 index 0000000..86a24e2 --- /dev/null +++ b/CCModule/MQTTModule.m @@ -0,0 +1,13 @@ +#import "MQTTModule.h" + +@implementation MQTTModule + +- (UIImage *)iconGlyph { + return [UIImage imageNamed:@"ModuleIcon" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil]; +} + +- (void)setSelected:(BOOL)selected { + [[NSNotificationCenter defaultCenter] postNotificationName:@"ch.jesseb0rn.mqttmodule.run" object:nil]; +} + +@end diff --git a/CCModule/Makefile b/CCModule/Makefile new file mode 100644 index 0000000..f36d3ae --- /dev/null +++ b/CCModule/Makefile @@ -0,0 +1,16 @@ +include $(THEOS)/makefiles/common.mk + +export TARGET = iphone:clang::11.0 +export ARCHS = arm64 + +BUNDLE_NAME = MQTTModule +MQTTModule_BUNDLE_EXTENSION = bundle +MQTTModule_FILES = MQTTModule.m +MQTTModule_PRIVATE_FRAMEWORKS = ControlCenterUIKit +MQTTModule_FRAMEWORKS = UIKit +MQTTModule_INSTALL_PATH = /Library/ControlCenter/Bundles/ + +after-install:: + install.exec "killall -9 SpringBoard" + +include $(THEOS_MAKE_PATH)/bundle.mk diff --git a/CCModule/Resources/Info.plist b/CCModule/Resources/Info.plist new file mode 100644 index 0000000..882ef7b --- /dev/null +++ b/CCModule/Resources/Info.plist @@ -0,0 +1,54 @@ + + + + + CFBundleName + MQTTModule + CFBundleExecutable + MQTTModule + CFBundleIdentifier + ch.jesseb0rn.mqttmodule + CFBundleDevelopmentRegion + English + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + MinimumOSVersion + 7.0 + UIDeviceFamily + + 1 + 2 + + NSPrincipalClass + MQTTModule + CFBundleSupportedPlatforms + + iPhoneOS + + CCSGetModuleSizeAtRuntime + + CCSModuleSize + + Portrait + + Height + 1 + Width + 1 + + Landscape + + Height + 1 + Width + 1 + + + + diff --git a/CCModule/Resources/ModuleIcon@2x.png b/CCModule/Resources/ModuleIcon@2x.png new file mode 100644 index 0000000..11e73fb Binary files /dev/null and b/CCModule/Resources/ModuleIcon@2x.png differ diff --git a/CCModule/Resources/ModuleIcon@3x.png b/CCModule/Resources/ModuleIcon@3x.png new file mode 100644 index 0000000..8d89135 Binary files /dev/null and b/CCModule/Resources/ModuleIcon@3x.png differ diff --git a/CCModule/Resources/SettingsIcon@2x.png b/CCModule/Resources/SettingsIcon@2x.png new file mode 100644 index 0000000..89a28ac Binary files /dev/null and b/CCModule/Resources/SettingsIcon@2x.png differ diff --git a/CCModule/Resources/SettingsIcon@3x.png b/CCModule/Resources/SettingsIcon@3x.png new file mode 100644 index 0000000..60f0d29 Binary files /dev/null and b/CCModule/Resources/SettingsIcon@3x.png differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..23c4f49 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +THEOS = /var/theos #Theos directory +ARCHS = arm64 arm64e #A11+ support +TARGET = iphone:clang::11.0 #min ios11, latest sdk + +#seems to cause problems, only use for release builds +#PACKAGE_VERSION = 1.0.1 + +include $(THEOS)/makefiles/common.mk + +TWEAK_NAME = MQTTModule +MQTTModule_CFLAGS = -fobjc-arc + +SUBPROJECTS += CCModule Tweak mqttmoduleprefs mqttmoduled #load all subprojects +include $(THEOS_MAKE_PATH)/aggregate.mk diff --git a/Tweak/Makefile b/Tweak/Makefile new file mode 100644 index 0000000..6f5909b --- /dev/null +++ b/Tweak/Makefile @@ -0,0 +1,14 @@ +INSTALL_TARGET_PROCESSES = SpringBoard + +ARCHS = arm64 arm64e +include $(THEOS)/makefiles/common.mk + +TWEAK_NAME = Tweak + +Tweak_FILES = Tweak.xm +Tweak_CFLAGS = -fobjc-arc + +Tweak_FRAMEWORKS = UIKit +Tweak_PRIVATE_FRAMEWORKS = ControlCenterUIKit + +include $(THEOS_MAKE_PATH)/tweak.mk diff --git a/Tweak/Tweak.plist b/Tweak/Tweak.plist new file mode 100644 index 0000000..10dc654 --- /dev/null +++ b/Tweak/Tweak.plist @@ -0,0 +1 @@ +{ Filter = { Bundles = ( "com.apple.springboard" ); }; } diff --git a/Tweak/Tweak.xm b/Tweak/Tweak.xm new file mode 100644 index 0000000..245753b --- /dev/null +++ b/Tweak/Tweak.xm @@ -0,0 +1,81 @@ +#import +#import +#import "../headers/NSTask.h" +#define FLAG_PLATFORMIZE (1 << 1) + +@interface CCUIModuleCollectionViewController : UIViewController +- (void)viewDidLoad; +- (void)dealloc; +- (void)startCommandModule:(NSNotification *)notification; +@end + +//preference vars +NSString * host; +NSInteger port; +NSString *topic; +NSString *msg; +NSInteger qos; + +static NSString *bundleIdentifier = @"ch.jesseb0rn.mqttprefs"; +static NSMutableDictionary *settings; + +%group ios13 +%hook CCUIModuleCollectionViewController +- (void)viewDidLoad { + %orig; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(publishMqtt:) name:@"ch.jesseb0rn.mqttmodule.run" object:nil]; +} + +- (void)dealloc { + %orig; + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} +%new +- (void)publishMqtt:(NSNotification *)notification { //this method is run upon receiving the notification that the user invoked my tweak + + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"MQTTModule" message: [NSString stringWithFormat:@"/usr/bin/mqtt %@ %ld %@ %@ %ld", host, port, topic, msg, qos] preferredStyle:UIAlertControllerStyleAlert]; + + + [self presentViewController:alert animated:YES completion:^{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { //must dispatch_async so the UI doesn't freeze while the script is running + + NSTask* task = [[NSTask alloc] init]; + [task setLaunchPath:@"/usr/bin/mqttmoduled"]; + [task setArguments: @[[NSString stringWithFormat:@"%@", host], [NSString stringWithFormat:@"%ld", port], [NSString stringWithFormat:@"%@", topic], [NSString stringWithFormat:@"%@", msg], [NSString stringWithFormat:@"%ld", qos]]]; + [task launch]; + + while ([task isRunning]) { + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]]; + } + + dispatch_sync(dispatch_get_main_queue(), ^{ //once the script is finished, update the UI + [alert dismissViewControllerAnimated:YES completion:nil]; + }); + }); + }]; + } +%end +%end + +%ctor { + + CFArrayRef keyList = CFPreferencesCopyKeyList((CFStringRef)bundleIdentifier, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + if (keyList) { + settings = (NSMutableDictionary *)CFBridgingRelease(CFPreferencesCopyMultiple(keyList, (CFStringRef)bundleIdentifier, kCFPreferencesCurrentUser, kCFPreferencesAnyHost)); + CFRelease(keyList); + } else { + settings = nil; + } + if (!settings) { + settings = [[NSMutableDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"/var/mobile/Library/Preferences/ch.jesseb0rn.mqttprefs.plist"]]; + } + + host = [settings valueForKey:@"host"]; + port = [[settings valueForKey:@"port"] integerValue]; + topic = [settings valueForKey:@"topic"]; + msg = [settings valueForKey:@"msg"]; + qos = [[settings valueForKey:@"qos"] integerValue]; + + %init(ios13); + +} diff --git a/headers/NSTask.h b/headers/NSTask.h new file mode 100644 index 0000000..6dd2735 --- /dev/null +++ b/headers/NSTask.h @@ -0,0 +1,58 @@ +@class NSURL, NSArray, NSDictionary; + +@interface NSTask : NSObject + +@property (copy) NSURL * executableURL; +@property (copy) NSArray * arguments; +@property (copy) NSDictionary * environment; +@property (copy) NSURL * currentDirectoryURL; +@property (retain) id standardInput; +@property (retain) id standardOutput; +@property (retain) id standardError; +@property (readonly) int processIdentifier; +@property (getter=isRunning,readonly) BOOL running; +@property (readonly) int terminationStatus; +@property (readonly) long long terminationReason; +@property (copy) id terminationHandler; +@property (assign) long long qualityOfService; ++(id)currentTaskDictionary; ++(id)launchedTaskWithDictionary:(id)arg1 ; ++(id)launchedTaskWithLaunchPath:(id)arg1 arguments:(id)arg2 ; ++(id)launchedTaskWithExecutableURL:(id)arg1 arguments:(id)arg2 error:(out id*)arg3 terminationHandler:(/*^block*/id)arg4 ; ++(id)allocWithZone:(NSZone*)arg1 ; +-(void)waitUntilExit; +-(NSURL *)executableURL; +-(id)currentDirectoryPath; +-(void)setArguments:(NSArray *)arg1 ; +-(void)setCurrentDirectoryPath:(id)arg1 ; +-(id)launchPath; +-(void)setLaunchPath:(id)arg1 ; +-(int)terminationStatus; +-(long long)terminationReason; +-(void)launch; +-(BOOL)launchAndReturnError:(id*)arg1 ; +-(void)setCurrentDirectoryURL:(NSURL *)arg1 ; +-(NSURL *)currentDirectoryURL; +-(void)setExecutableURL:(NSURL *)arg1 ; +-(void)interrupt; +-(long long)suspendCount; +-(void)setStandardInput:(id)arg1 ; +-(void)setStandardOutput:(id)arg1 ; +-(void)setStandardError:(id)arg1 ; +-(id)standardInput; +-(id)standardOutput; +-(id)standardError; +-(id)init; +-(NSDictionary *)environment; +-(BOOL)isRunning; +-(BOOL)suspend; +-(BOOL)resume; +-(void)setEnvironment:(NSDictionary *)arg1 ; +-(void)setQualityOfService:(long long)arg1 ; +-(void)setTerminationHandler:(id)arg1 ; +-(int)processIdentifier; +-(id)terminationHandler; +-(long long)qualityOfService; +-(void)terminate; +-(NSArray *)arguments; +@end \ No newline at end of file diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control new file mode 100644 index 0000000..0d773ce --- /dev/null +++ b/layout/DEBIAN/control @@ -0,0 +1,9 @@ +Package: ch.jesseb0rn.mqttmodule +Name: MQTTModule +Depends: mobilesubstrate, com.opa334.ccsupport, ch.jesseb0rn.mqtt +Version: 1.0.2 +Architecture: iphoneos-arm +Description: Send a MQTT message from your CC +Maintainer: jesseb0rn +Author: jesseb0rn +Section: Control Center Modules diff --git a/layout/DEBIAN/postinst b/layout/DEBIAN/postinst new file mode 100644 index 0000000..03f9ae2 --- /dev/null +++ b/layout/DEBIAN/postinst @@ -0,0 +1,6 @@ +#!/bin/bash + +chown root:wheel /usr/bin/mqttmoduled +chmod +s /usr/bin/mqttmoduled + +exit 0 diff --git a/mqttmoduled/Makefile b/mqttmoduled/Makefile new file mode 100644 index 0000000..2ac31b1 --- /dev/null +++ b/mqttmoduled/Makefile @@ -0,0 +1,11 @@ +include $(THEOS)/makefiles/common.mk + +TOOL_NAME = mqttmoduled + +mqttmoduled_FILES = main.m +mqttmoduled_CFLAGS = -fobjc-arc + +mqttmoduled_CODESIGN_FLAGS = -Sent.xml + + +include $(THEOS_MAKE_PATH)/tool.mk diff --git a/mqttmoduled/ent.xml b/mqttmoduled/ent.xml new file mode 100644 index 0000000..7193d32 --- /dev/null +++ b/mqttmoduled/ent.xml @@ -0,0 +1,10 @@ + + + + platform-application + + com.apple.private.security.no-container + + + + \ No newline at end of file diff --git a/mqttmoduled/main.m b/mqttmoduled/main.m new file mode 100644 index 0000000..c1b2952 --- /dev/null +++ b/mqttmoduled/main.m @@ -0,0 +1,28 @@ +#include +#import "../headers/NSTask.h" + +int main(int argc, char *argv[], char *envp[]) { + + NSString * host = [NSString stringWithUTF8String:argv[1]]; + NSInteger port = 1883; + port = strtol(argv[2], NULL, 10); + NSString *topic = [NSString stringWithUTF8String:argv[3]]; + NSString *msg = [NSString stringWithUTF8String:argv[4]]; + NSInteger qos = 0; + qos = strtol(argv[5], NULL, 10); + setuid(0); //make us root + setgid(0); + if (getuid() != 0) { //Check for root permissions + printf("root accsess denied"); + } + NSTask *task = [[NSTask alloc] init]; + task.launchPath = @"/usr/bin/mqtt"; + [task setArguments: @[[NSString stringWithFormat:@"%@", host], [NSString stringWithFormat:@"%ld", port], [NSString stringWithFormat:@"%@", topic], [NSString stringWithFormat:@"%@", msg], [NSString stringWithFormat:@"%ld", qos]]]; + [task launch]; + + while ([task isRunning]) { //Wait for task to finnish + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]]; + } + + return 0; +} diff --git a/mqttmoduleprefs/Makefile b/mqttmoduleprefs/Makefile new file mode 100644 index 0000000..80a4853 --- /dev/null +++ b/mqttmoduleprefs/Makefile @@ -0,0 +1,15 @@ +include $(THEOS)/makefiles/common.mk +ARCHS = arm64 arm64e +BUNDLE_NAME = mqttmoduleprefs + +mqttmoduleprefs_FILES = jmpRootListController.m +mqttmoduleprefs_INSTALL_PATH = /Library/PreferenceBundles +mqttmoduleprefs_FRAMEWORKS = UIKit +mqttmoduleprefs_PRIVATE_FRAMEWORKS = Preferences +mqttmoduleprefs_CFLAGS = -fobjc-arc + +include $(THEOS_MAKE_PATH)/bundle.mk + +internal-stage:: + $(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END) + $(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/mqttmoduleprefs.plist$(ECHO_END) diff --git a/mqttmoduleprefs/Resources/Info.plist b/mqttmoduleprefs/Resources/Info.plist new file mode 100644 index 0000000..6647fa6 --- /dev/null +++ b/mqttmoduleprefs/Resources/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + mqttmoduleprefs + CFBundleIdentifier + ch.jesseb0rn.mqttprefs + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + jmpRootListController + + diff --git a/mqttmoduleprefs/Resources/Root.plist b/mqttmoduleprefs/Resources/Root.plist new file mode 100644 index 0000000..92fea1d --- /dev/null +++ b/mqttmoduleprefs/Resources/Root.plist @@ -0,0 +1,107 @@ + + + + + items + + + cell + PSEditTextCell + default + broker.hivemq.com + defaults + ch.jesseb0rn.mqttprefs + key + host + label + hostname + + + cell + PSEditTextCell + default + 1883 + defaults + ch.jesseb0rn.mqttprefs + key + port + label + port + + + cell + PSEditTextCell + default + jesseb0rn/test + defaults + ch.jesseb0rn.mqttprefs + key + topic + label + topic + + + cell + PSEditTextCell + default + msg + defaults + ch.jesseb0rn.mqttprefs + key + msg + label + message + + + cell + PSEditTextCell + default + 0 + defaults + ch.jesseb0rn.mqttprefs + key + qos + label + qos + + + cell + PSGroupCell + label + Apply + + + action + respring + cell + PSButtonCell + label + Apply + + + cell + PSGroupCell + label + Open source + + + action + github + cell + PSButtonCell + label + GitHub repo + + + action + donate + cell + PSButtonCell + label + PayPal + + + title + MQTTModule + + diff --git a/mqttmoduleprefs/Resources/icon@2x.png b/mqttmoduleprefs/Resources/icon@2x.png new file mode 100644 index 0000000..89a28ac Binary files /dev/null and b/mqttmoduleprefs/Resources/icon@2x.png differ diff --git a/mqttmoduleprefs/Resources/icon@3x.png b/mqttmoduleprefs/Resources/icon@3x.png new file mode 100644 index 0000000..60f0d29 Binary files /dev/null and b/mqttmoduleprefs/Resources/icon@3x.png differ diff --git a/mqttmoduleprefs/Resources/icon@5x.png b/mqttmoduleprefs/Resources/icon@5x.png new file mode 100644 index 0000000..d6dfce6 Binary files /dev/null and b/mqttmoduleprefs/Resources/icon@5x.png differ diff --git a/mqttmoduleprefs/entry.plist b/mqttmoduleprefs/entry.plist new file mode 100644 index 0000000..e431a14 --- /dev/null +++ b/mqttmoduleprefs/entry.plist @@ -0,0 +1,21 @@ + + + + + entry + + bundle + mqttmoduleprefs + cell + PSLinkCell + detail + jmpRootListController + icon + icon.png + isController + + label + MQTTModule + + + diff --git a/mqttmoduleprefs/jmpRootListController.h b/mqttmoduleprefs/jmpRootListController.h new file mode 100644 index 0000000..a2aa546 --- /dev/null +++ b/mqttmoduleprefs/jmpRootListController.h @@ -0,0 +1,5 @@ +#import + +@interface jmpRootListController : PSListController + +@end diff --git a/mqttmoduleprefs/jmpRootListController.m b/mqttmoduleprefs/jmpRootListController.m new file mode 100644 index 0000000..ca8bc45 --- /dev/null +++ b/mqttmoduleprefs/jmpRootListController.m @@ -0,0 +1,40 @@ +#include "jmpRootListController.h" + +@interface NSTask : NSObject + +-(id)init; +-(void)setArguments:(NSArray *)arg1 ; +-(void)setLaunchPath:(id)arg1 ; +-(void)launch; +@end + +@implementation jmpRootListController + +- (NSArray *)specifiers { + if (!_specifiers) { + _specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self]; + } + + return _specifiers; +} +- (void) respring { + NSTask* task = [[NSTask alloc] init]; + [task setLaunchPath:@"/bin/bash"]; + [task setArguments:@[ @"-c", @"/usr/bin/killall SpringBoard" ]]; + [task launch]; +} +- (void) github { + [[UIApplication sharedApplication] + openURL:[NSURL URLWithString:@"https://github.com/jesseb0rn/mqttmodule"] + options:@{} + completionHandler:nil]; +} +- (void) donate { + + [[UIApplication sharedApplication] + openURL:[NSURL URLWithString:@"https://bit.ly/jb0donate"] + options:@{} + completionHandler:nil]; + +} +@end