|
|
@@ -0,0 +1,306 @@
|
|
|
+//
|
|
|
+// connectDeviceManager.m
|
|
|
+// 隐私保护
|
|
|
+//
|
|
|
+// Created by xd h on 2023/10/9.
|
|
|
+//
|
|
|
+
|
|
|
+//第三方 瑞云 的链接服务
|
|
|
+#import "connectDeviceManager.h"
|
|
|
+
|
|
|
+#import <RayProxy/RaylinkProxy.h>
|
|
|
+#import <CocoaAsyncSocket/GCDAsyncSocket.h>
|
|
|
+
|
|
|
+@interface connectDeviceManager ()<
|
|
|
+GCDAsyncSocketDelegate,
|
|
|
+RaylinkProxyDelegate
|
|
|
+>
|
|
|
+{
|
|
|
+ dispatch_queue_t initProxyQueue;
|
|
|
+}
|
|
|
+
|
|
|
+@property (nonatomic, strong) NSTimer *connectCheckTimer;
|
|
|
+
|
|
|
+@property (nonatomic, strong) GCDAsyncSocket *socket;
|
|
|
+
|
|
|
+@property (nonatomic, strong) GCDAsyncSocket *serverSocket;
|
|
|
+
|
|
|
+@property (nonatomic, assign) BOOL sdnConnected;
|
|
|
+@property (nonatomic, assign) BOOL peerConnected;
|
|
|
+
|
|
|
+@property (nonatomic, assign) NSInteger tcpPort;
|
|
|
+
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@implementation connectDeviceManager
|
|
|
+static connectDeviceManager *connectDeviceManagerInstance = nil;
|
|
|
++(connectDeviceManager *)shareInstance;
|
|
|
+{
|
|
|
+ static dispatch_once_t onceToken;
|
|
|
+
|
|
|
+ dispatch_once(&onceToken, ^{
|
|
|
+ connectDeviceManagerInstance = [[connectDeviceManager alloc] init];
|
|
|
+ connectDeviceManagerInstance.curConnectDeviceState = DeviceConnectUnknown;
|
|
|
+ });
|
|
|
+
|
|
|
+ return connectDeviceManagerInstance;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#pragma mark 根据扫码的sn获取第三方信息
|
|
|
+-(void)getThridMsgBySN:(NSString*)snStr
|
|
|
+{
|
|
|
+ _curConnectDeviceState = DeviceConnectGetThridMsging;
|
|
|
+
|
|
|
+ NSMutableDictionary *paraDict = [NSMutableDictionary new];
|
|
|
+ [paraDict setValue:snStr forKey:@"sn"];
|
|
|
+
|
|
|
+ KWeakSelf
|
|
|
+ [[netWorkManager shareInstance] CommonGetWithCallBackCode:getThirdIdBySn Parameters:paraDict success:^(id _Nonnull responseObject) {
|
|
|
+
|
|
|
+
|
|
|
+ weakSelf.DeviceThirdIdMod = [[DeviceThirdIdModel alloc] initWithDictionary:responseObject error:nil];
|
|
|
+
|
|
|
+ if(weakSelf.DeviceThirdIdMod.status == 0)
|
|
|
+ {
|
|
|
+ weakSelf.curConnectDeviceState = DeviceConnectGetThridOK;
|
|
|
+ [weakSelf initRuiyunSDKFun];
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ } failure:^(NSError * _Nonnull error) {
|
|
|
+ HLog("网络报错");
|
|
|
+ }];
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark 初始化瑞云的SDK等
|
|
|
+- (void)initRuiyunSDKFun{
|
|
|
+
|
|
|
+
|
|
|
+ self.sdnConnected = NO;
|
|
|
+ self.peerConnected = NO;
|
|
|
+
|
|
|
+ //self.sendBtn.enabled = NO;
|
|
|
+
|
|
|
+ //self.sdnConnectStateLab.text = @"SDN state: Connectting";
|
|
|
+ //self.sdnIDLab.text = @"My SDN ID:";
|
|
|
+
|
|
|
+ RaylinkProxy.sharedManager.delegate = self;
|
|
|
+
|
|
|
+ initProxyQueue = dispatch_queue_create("init_proxy", 0);
|
|
|
+
|
|
|
+ NSURL *logUrl = [[NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject URLByAppendingPathComponent:@"logs"];
|
|
|
+
|
|
|
+ if (![NSFileManager.defaultManager fileExistsAtPath:logUrl.path]) {
|
|
|
+ [NSFileManager.defaultManager createDirectoryAtURL:logUrl withIntermediateDirectories:YES attributes:NULL error:NULL];
|
|
|
+ }
|
|
|
+
|
|
|
+ dispatch_async(initProxyQueue, ^{
|
|
|
+ NSData *sdnInfo = [NSData dataWithContentsOfURL:[[NSBundle.mainBundle bundleURL] URLByAppendingPathComponent:@"planet.1ali_3ry_peer"]];
|
|
|
+
|
|
|
+ /// 1. 初始化代理库
|
|
|
+ [RaylinkProxy.sharedManager initProxy:logUrl.path rootSdnInfo:sdnInfo];
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ /// 作为服务端时,启动端口监听
|
|
|
+ self.serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
|
|
|
+
|
|
|
+ if ([self.serverSocket acceptOnPort:0 error:NULL]) {
|
|
|
+ //self.serverPortLab.text = [NSString stringWithFormat: @"server port: %d", self.serverSocket.localPort];
|
|
|
+ NSLog(@"accept ok %d",self.serverSocket.localPort);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /// 启动定时器监听 SND 连接状态
|
|
|
+ self.connectCheckTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 repeats:YES block:^(NSTimer * _Nonnull timer) {
|
|
|
+
|
|
|
+ /// 2. 监听SDN 连接状态
|
|
|
+ bool connected = [RaylinkProxy.sharedManager isSdnConnected];
|
|
|
+ if (self.sdnConnected == connected) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ self.sdnConnected = connected;
|
|
|
+
|
|
|
+ if (self.sdnConnected) {
|
|
|
+
|
|
|
+ //self.sdnConnectStateLab.text = @"SDN state: Connected";
|
|
|
+ //self.sdnIDLab.text = [@"My SDN ID: " stringByAppendingString:[RaylinkProxy.sharedManager getSdnId]];
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+ //self.sdnConnectStateLab.text = @"SDN state: Connectting";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }];
|
|
|
+
|
|
|
+
|
|
|
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
+ mainBlock(^{
|
|
|
+ [self onConnectFun];
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+- (void)onConnectFun{
|
|
|
+
|
|
|
+ if (self.peerConnected == YES) {
|
|
|
+ [self disconnect];
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ _curConnectDeviceState = DeviceConnectDeciceing;
|
|
|
+
|
|
|
+
|
|
|
+ /// 3. 根据对端的 SDN ID 创建连接
|
|
|
+ [RaylinkProxy.sharedManager createNewConnection:self.DeviceThirdIdMod.data.sdnId];
|
|
|
+
|
|
|
+ /// 4. 创建 HttpService
|
|
|
+ self.tcpPort = [RaylinkProxy.sharedManager createHttpService:self.DeviceThirdIdMod.data.sdnId];
|
|
|
+ self.tcpPortStr = [[NSString alloc] initWithFormat:@"%ld",self.tcpPort];
|
|
|
+
|
|
|
+ self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
|
|
|
+
|
|
|
+ /// 6. 添加端口防火墙
|
|
|
+ [RaylinkProxy.sharedManager addSdnId:self.DeviceThirdIdMod.data.sdnId allowPort:9100];
|
|
|
+
|
|
|
+ //[self.connectBtn setEnabled:NO];
|
|
|
+
|
|
|
+ //[self.connectBtn setTitle:@"连接中..." forState:UIControlStateDisabled];
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (void)disconnect {
|
|
|
+// [RaylinkProxy.sharedManager closeConnection:self.sdnIdTF.text];
|
|
|
+// [RaylinkProxy.sharedManager closeHttpService:self.sdnIdTF.text];
|
|
|
+// [self.connectBtn setTitle:@"连接" forState:UIControlStateNormal];
|
|
|
+ self.peerConnected = NO;
|
|
|
+}
|
|
|
+
|
|
|
+- (IBAction)onClickSend:(id)sender {
|
|
|
+
|
|
|
+// if (self.messageTF.text.length <= 0) {
|
|
|
+// return;
|
|
|
+// }
|
|
|
+
|
|
|
+ [self.socket writeData:[@"111" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket {
|
|
|
+
|
|
|
+ NSLog(@"didAcceptNewSocket");
|
|
|
+
|
|
|
+
|
|
|
+ [newSocket setDelegate:self delegateQueue:dispatch_get_main_queue()];
|
|
|
+
|
|
|
+ NSThread *revcThread = [[NSThread alloc] initWithBlock:^{
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ [newSocket readDataWithTimeout:-1 tag:0];
|
|
|
+ [NSThread sleepForTimeInterval:0.1];
|
|
|
+ }
|
|
|
+ }];
|
|
|
+
|
|
|
+ [revcThread start];
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (void)onProxyConnected:(NSString *)sdnId status:(int)status {
|
|
|
+
|
|
|
+
|
|
|
+ if (status == 0) {
|
|
|
+ /// 6. 等待连接成功回调,创建 TCP socket 连接 HttpService 的端口
|
|
|
+ [self.socket connectToHost:@"127.0.0.1" onPort:self.tcpPort error:NULL];
|
|
|
+
|
|
|
+ _curConnectDeviceState = DeviceConnectDeciceOk;
|
|
|
+// [self.connectBtn setTitle:@"连接成功" forState:UIControlStateDisabled];
|
|
|
+// [self.sendBtn setEnabled:YES];
|
|
|
+ } else {
|
|
|
+// [self.connectBtn setTitle:@"连接中..." forState:UIControlStateDisabled];
|
|
|
+// [self.sendBtn setEnabled:NO];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
|
|
|
+
|
|
|
+ NSLog(@"didConnectToHost %d", port);
|
|
|
+
|
|
|
+ NSThread *thread = [[NSThread alloc] initWithBlock:^{
|
|
|
+ while (true) {
|
|
|
+
|
|
|
+ [self.socket readDataWithTimeout:-1 tag:0];
|
|
|
+ [NSThread sleepForTimeInterval:0.1];
|
|
|
+
|
|
|
+ }
|
|
|
+ }];
|
|
|
+
|
|
|
+ [thread start];
|
|
|
+
|
|
|
+ /// 7. Socket 连接成功后,通过 socket 发送, self.peerPortTF 为对端服务端口
|
|
|
+ [sock writeData:[[NSString stringWithFormat:@"CONNECT 127.0.0.1:%@ HTTP/1.0\r\n\r\n", @"9100"] dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
|
|
|
+
|
|
|
+ NSLog(@"readDataToData");
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
|
|
|
+{
|
|
|
+ NSLog(@"socket:%p didWriteDataWithTag:%ld", sock, tag);
|
|
|
+}
|
|
|
+
|
|
|
+- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
|
|
|
+
|
|
|
+
|
|
|
+ if (tag == 0) {
|
|
|
+
|
|
|
+ NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
|
+
|
|
|
+ /// 8. 收到包含 `HTTP/1.0 200`的字符串,则认为连接成功。可以正常给对端发消息了
|
|
|
+ if ([str containsString:@"HTTP/1.0 200"]) {
|
|
|
+ NSLog(@"Connected");
|
|
|
+ self.peerConnected = YES;
|
|
|
+// self.connectBtn.enabled = YES;
|
|
|
+// [self.connectBtn setTitle:@"断开连接" forState:UIControlStateNormal];
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //self.revcLab.text = [NSString stringWithFormat:@"接收:%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]];
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#pragma mark 保持卡密码
|
|
|
+-(void)updateCardInfoBySN:(NSString*)snStr withPwdStr:(NSString*)pwd
|
|
|
+{
|
|
|
+
|
|
|
+
|
|
|
+ NSMutableDictionary *paraDict = [NSMutableDictionary new];
|
|
|
+ [paraDict setValue:snStr forKey:@"sn"];
|
|
|
+ [paraDict setValue:pwd forKey:@"password"];
|
|
|
+
|
|
|
+ KWeakSelf
|
|
|
+ [[netWorkManager shareInstance] CommonGetWithCallBackCode:updateCardInfo Parameters:paraDict success:^(id _Nonnull responseObject) {
|
|
|
+
|
|
|
+
|
|
|
+ SuperModel*model = [[SuperModel alloc] initWithDictionary:responseObject error:nil];
|
|
|
+
|
|
|
+ if(model.status == 0)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ } failure:^(NSError * _Nonnull error) {
|
|
|
+ HLog("网络报错");
|
|
|
+ }];
|
|
|
+}
|
|
|
+@end
|