
Objective-C 实现代码
头文件(APP.h)
objc
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
// 硬件交互相关的函数声明(对应原DLL的导出函数,Mac下替换为dylib)
// 注意:需根据硬件厂商的Mac版dylib修改函数签名
typedef int (*InitializeUSBFunc)(int);
typedef void (*CloseUSBFunc)(void);
typedef int (*BuzzerFunc)(int, int);
typedef int (*CardEraseFunc)(int, int, NSMutableString*);
typedef int (*GuestCardFunc)(int, int, int, int, int, int, NSString*, NSString*, NSString*, NSMutableString*);
typedef int (*ReadCardFunc)(int, uint8_t*, int);
@interface CyberWin_LocakAPP : NSObject
+ (NSString *)futureWindow_MeiPing_getSign:(uint8_t *)bufCard length:(NSUInteger)length;
+ (NSString *)copyBytes:(uint8_t *)bytes start:(NSInteger)start length:(NSInteger)length totalLength:(NSUInteger)totalLength;
@end
@interface CyberWin_hoteldoor_prousbv10_2024 : NSObject
+ (int)initializeUSB:(int)d12;
+ (void)closeUSB;
+ (int)cardErase:(int)d12 dlsCoID:(int)dlsCoID cardNo:(NSMutableString *)cardNo;
@end
@interface APP : NSObject
@property (nonatomic, assign) uint8_t carddata[128];
@property (nonatomic, copy) NSString *idPhotoSavePath;
@property (nonatomic, assign) uint8_t bufCard[129]; // 128+1
@property (nonatomic, assign) uint8_t bufCard_v10[201]; // 200+1
@property (nonatomic, assign) int st;
// 核心方法
- (NSString *)start:(NSDictionary *)obj;
- (NSString *)status:(NSDictionary *)obj;
- (NSString *)checkingout:(NSDictionary *)obj;
- (NSString *)checkingin:(NSDictionary *)obj;
- (NSString *)getsign:(NSDictionary *)obj;
// 工具方法
- (BOOL)rdCard;
- (BOOL)rdCard_v10;
- (NSString *)copyBytes:(uint8_t *)bytes start:(NSInteger)start length:(NSInteger)length totalLength:(NSUInteger)totalLength;
+ (void)writeLogWithCaptureType:(NSString *)capturetype type:(NSString *)type content:(NSString *)s;
@end
实现文件(APP.m)
objc
#import "APP.h"
#include <dlfcn.h>
#include <string.h>
#include <time.h>
// 加载Mac版的dylib(需替换为实际的dylib路径)
static void *gDylibHandle = NULL;
static InitializeUSBFunc gInitializeUSB = NULL;
static CloseUSBFunc gCloseUSB = NULL;
static BuzzerFunc gBuzzer = NULL;
static CardEraseFunc gCardErase = NULL;
static GuestCardFunc gGuestCard = NULL;
static ReadCardFunc gReadCard = NULL;
static ReadCardFunc gReadCard_v10 = NULL;
@implementation CyberWin_LocakAPP
+ (NSString *)futureWindow_MeiPing_getSign:(uint8_t *)bufCard length:(NSUInteger)length {
NSString *futureWindow = [[NSString alloc] initWithBytes:bufCard length:length encoding:NSASCIIStringEncoding];
NSString *subStr = [self copyBytes:bufCard start:25 length:8 totalLength:length];
if ([subStr isEqualToString:@"FFFFFFFF"]) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"提示"];
[alert setInformativeText:@"此卡是空白卡,请换一张能开门的卡"];
[alert addButtonWithTitle:@"确定"];
[alert runModal];
return @"此卡是空白卡,请换一张能开门的卡";
}
NSString *s = [self copyBytes:bufCard start:11 length:4 totalLength:length];
NSUInteger i = strtoul([s UTF8String], NULL, 16) % 16384;
NSString *s2 = [self copyBytes:bufCard start:9 length:2 totalLength:length];
i += strtoul([s UTF8String], NULL, 16) * 65536;
NSUInteger i2 = strtoul([self copyBytes:bufCard start:9 length:2 totalLength:length], NULL, 16) * 65536 + strtoul([self copyBytes:bufCard start:11 length:4 totalLength:length], NULL, 16) % 16383;
return [NSString stringWithFormat:@"%lu", i2];
}
+ (NSString *)copyBytes:(uint8_t *)bytes start:(NSInteger)start length:(NSInteger)length totalLength:(NSUInteger)totalLength {
if (start < 1) {
start = 1;
}
NSInteger realStart = start - 1;
if (realStart + length > totalLength) {
length = totalLength - realStart;
}
uint8_t *subBytes = malloc(length);
memcpy(subBytes, bytes + realStart, length);
NSString *result = [[NSString alloc] initWithBytes:subBytes length:length encoding:NSASCIIStringEncoding];
free(subBytes);
return result;
}
@end
@implementation CyberWin_hoteldoor_prousbv10_2024
+ (void)loadDylib {
// 替换为实际的dylib路径,比如@"/usr/local/lib/proRFLV102024.dylib"
NSString *dylibPath = @"proRFLV102024.dylib";
gDylibHandle = dlopen([dylibPath UTF8String], RTLD_LAZY);
if (gDylibHandle) {
gInitializeUSB = (InitializeUSBFunc)dlsym(gDylibHandle, "initializeUSB");
gCloseUSB = (CloseUSBFunc)dlsym(gDylibHandle, "CloseUSB");
gCardErase = (CardEraseFunc)dlsym(gDylibHandle, "CardErase");
// 其他函数同理加载
} else {
NSLog(@"加载dylib失败:%s", dlerror());
}
}
+ (int)initializeUSB:(int)d12 {
if (!gDylibHandle) {
[self loadDylib];
}
if (gInitializeUSB) {
return gInitializeUSB(d12);
}
return -1;
}
+ (void)closeUSB {
if (gCloseUSB) {
gCloseUSB();
}
if (gDylibHandle) {
dlclose(gDylibHandle);
gDylibHandle = NULL;
}
}
+ (int)cardErase:(int)d12 dlsCoID:(int)dlsCoID cardNo:(NSMutableString *)cardNo {
if (gCardErase) {
return gCardErase(d12, dlsCoID, cardNo);
}
return -1;
}
@end
@implementation APP
- (instancetype)init {
self = [super init];
if (self) {
memset(_carddata, 0, 128);
memset(_bufCard, 0, 129);
memset(_bufCard_v10, 0, 201);
_st = 0;
_idPhotoSavePath = @"";
// 预加载dylib
[CyberWin_hoteldoor_prousbv10_2024 loadDylib];
}
return self;
}
- (NSString *)start:(NSDictionary *)obj {
NSString *param1 = obj[@"param1"];
return @"随机预安装插件";
}
- (NSString *)status:(NSDictionary *)obj {
// 调用蜂鸣器函数(需确保dylib中存在Buzzer函数)
if (gBuzzer) {
gBuzzer(1, 50);
}
return @"当你听到设备蜂鸣器,说明设备已经连接";
}
- (NSString *)checkingout:(NSDictionary *)obj {
NSString *s = @"注销卡片";
NSString *param = obj[@"param"];
// 解析协议(原CyberWinProtocol,需自行实现协议解析逻辑,这里简化为字典模拟)
NSDictionary *protocolDict = [self parseProtocol:param];
NSString *hotelSign = protocolDict[@"hotelsign"];
int hotelSignInt = [hotelSign intValue];
// 初始化USB设备
int st读卡器 = [CyberWin_hoteldoor_prousbv10_2024 initializeUSB:1];
if (st读卡器 != 0) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"提示"];
[alert setInformativeText:@"设备打开失败"];
[alert addButtonWithTitle:@"确定"];
[alert runModal];
return @"打开端口失败";
}
// 注销卡片
NSCursor *waitCursor = [NSCursor waitCursor];
[waitCursor set];
NSMutableString *cardNoStr = [NSMutableString stringWithCapacity:100];
int st = [CyberWin_hoteldoor_prousbv10_2024 cardErase:1 dlsCoID:hotelSignInt cardNo:cardNoStr];
[NSCursor arrowCursor].set;
if (st != 0) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"提示"];
[alert setInformativeText:[NSString stringWithFormat:@"注销失败\n%d", st]];
[alert addButtonWithTitle:@"确定"];
[alert runModal];
s = [NSString stringWithFormat:@"%@:注销失败%d", s, st];
} else {
s = [NSString stringWithFormat:@"%@:成功", s];
}
[CyberWin_hoteldoor_prousbv10_2024 closeUSB];
return s;
}
- (NSString *)checkingin:(NSDictionary *)obj {
NSString *s = @"酒店入住发卡";
NSString *param = obj[@"param"];
// 解析协议(自行实现,这里简化)
NSDictionary *protocolDict = [self parseProtocol:param];
NSString *lockNoServer = protocolDict[@"lockno"];
NSString *hotelSign = protocolDict[@"hotelsign"];
NSString *checkingouttime = protocolDict[@"checkingouttime"];
int hotelSignInt = [hotelSign intValue];
// 校验锁号长度
if (lockNoServer.length < 6) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"提示"];
[alert setInformativeText:[NSString stringWithFormat:@"锁号长度错误=%@", lockNoServer]];
[alert addButtonWithTitle:@"确定"];
[alert runModal];
return @"";
}
// 初始化USB设备
int st = [CyberWin_hoteldoor_prousbv10_2024 initializeUSB:1];
if (st != 0) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"提示"];
[alert setInformativeText:@"设备打开失败"];
[alert addButtonWithTitle:@"确定"];
[alert runModal];
return @"打开端口失败";
}
// 准备发卡参数
NSCursor *waitCursor = [NSCursor waitCursor];
[waitCursor set];
// 获取当前时间(yyMMddHHmmss)
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyMMddHHmmss"];
NSString *openTime = [formatter stringFromDate:[NSDate date]];
// 反锁标志
int antiLockSign = 1;
int dai = 1;
// 调用发卡函数(需确保dylib中存在GuestCard_原始函数)
NSMutableString *cardHexStr = [NSMutableString stringWithCapacity:500];
st = 0; // 替换为实际的GuestCard_原始调用,这里先置0模拟
if (gGuestCard) {
st = gGuestCard(1, hotelSignInt, 0, dai, antiLockSign, 0, openTime, checkingouttime, lockNoServer, cardHexStr);
}
[NSCursor arrowCursor].set;
if (st != 0) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"提示"];
[alert setInformativeText:[NSString stringWithFormat:@"调用发卡函数失败\n%d", st]];
[alert addButtonWithTitle:@"确定"];
[alert runModal];
s = [NSString stringWithFormat:@"%@调用发卡函数失败", s];
} else {
s = [NSString stringWithFormat:@"%@制卡成功V2024%@", s, lockNoServer];
}
[CyberWin_hoteldoor_prousbv10_2024 closeUSB];
return s;
}
- (NSString *)getsign:(NSDictionary *)obj {
if (![self rdCard_v10]) {
return @"读卡失败";
}
return [CyberWin_LocakAPP futureWindow_MeiPing_getSign:self.bufCard_v10 length:200];
}
- (BOOL)rdCard {
NSCursor *waitCursor = [NSCursor waitCursor];
[waitCursor set];
int st = 0;
if (gReadCard) {
st = gReadCard(1, self.bufCard, 129);
}
if (st != 0) {
NSString *msg = st == 1 ? @"请放一张卡在发卡器上面,确保门锁软件可以正常发卡,然后调试接口" : [NSString stringWithFormat:@"读卡失败\n%d", st];
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:st == 1 ? @"读卡失败(返回值=1)" : @"提示"];
[alert setInformativeText:msg];
[alert addButtonWithTitle:@"确定"];
[alert runModal];
[NSCursor arrowCursor].set;
return NO;
}
NSString *subStr = [self copyBytes:self.bufCard start:5 length:2 totalLength:129];
if (![subStr isEqualToString:@"01"]) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"提示"];
[alert setInformativeText:@"发卡器的感应区无卡"];
[alert addButtonWithTitle:@"确定"];
[alert runModal];
[NSCursor arrowCursor].set;
return NO;
}
[NSCursor arrowCursor].set;
return YES;
}
- (BOOL)rdCard_v10 {
if (gReadCard_v10) {
self.st = gReadCard_v10(1, self.bufCard_v10, 201);
} else {
self.st = -1;
}
if (self.st != 0) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"提示"];
[alert setInformativeText:[NSString stringWithFormat:@"读卡失败%d", self.st]];
[alert addButtonWithTitle:@"确定"];
[alert runModal];
return NO;
}
return YES;
}
- (NSString *)copyBytes:(uint8_t *)bytes start:(NSInteger)start length:(NSInteger)length totalLength:(NSUInteger)totalLength {
return [CyberWin_LocakAPP copyBytes:bytes start:start length:length totalLength:totalLength];
}
+ (void)writeLogWithCaptureType:(NSString *)capturetype type:(NSString *)type content:(NSString *)s {
NSDate *now = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy年MM月dd日"];
NSString *dateStr = [dateFormatter stringFromDate:now];
NSString *logPath = [NSString stringWithFormat:@"%@/log/%@/%@", [[NSBundle mainBundle] bundlePath], capturetype, dateStr];
NSFileManager *fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:logPath isDirectory:NULL]) {
NSError *error = nil;
[fm createDirectoryAtPath:logPath withIntermediateDirectories:YES attributes:nil error:&error];
if (error) {
NSLog(@"创建日志目录失败:%@", error.localizedDescription);
return;
}
}
NSString *filePath = [logPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_log.log", type]];
NSString *logContent = [NSString stringWithFormat:@"==============================\n%@<<<<<<<<<<<<<<<<<<<<<<<<<<\n%@\n\n", [NSDate localizedStringFromDate:now dateStyle:NSDateFormatterFullStyle timeStyle:NSDateFormatterFullStyle], s];
NSError *error = nil;
if (![logContent writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]) {
NSLog(@"写入日志失败:%@", error.localizedDescription);
}
}
// 模拟协议解析(需根据实际协议实现)
- (NSDictionary *)parseProtocol:(NSString *)param {
// 这里只是模拟,实际需要解析未来之窗协议的字符串为字典
return @{
@"hotelsign": @"123",
@"lockno": @"123456",
@"checkingouttime": [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]
};
}
@end
关键说明
- dylib 加载 :使用
dlopen/dlsym加载 Mac 版的动态库,需将代码中的proRFLV102024.dylib替换为硬件厂商提供的实际 dylib 路径和文件名。 - 协议解析 :原代码中的
CyberWinProtocol协议解析逻辑需要你根据实际的 "未来之窗协议" 自行实现,代码中用parseProtocol方法做了模拟。 - 硬件函数调用 :原 C# 中的
GuestCard_原始、CardErase等函数,需要确保 Mac 版 dylib 中有对应的函数,且函数签名与代码中的 typedef 一致。 - 路径处理 :日志路径使用
NSBundle mainBundle的路径,你可以根据需求修改为自定义路径(如用户文档目录)。
阿雪技术观
在科技发展浪潮中,我们不妨积极投身技术共享。不满足于做受益者,更要主动担当贡献者。无论是分享代码、撰写技术博客,还是参与开源项目维护改进,每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地,我们携手在此探索硅基生命,为科技进步添砖加瓦。
Hey folks, in this wild tech - driven world, why not dive headfirst into the whole tech - sharing scene? Don't just be the one reaping all the benefits; step up and be a contributor too. Whether you're tossing out your code snippets, hammering out some tech blogs, or getting your hands dirty with maintaining and sprucing up open - source projects, every little thing you do might just end up being a massive force that pushes tech forward. And guess what? The Eastern FairyAlliance is this awesome place where we all come together. We're gonna team up and explore the whole silicon - based life thing, and in the process, we'll be fueling the growth of technology.