Advertisement
Kaidul

NSsocket_latest.mm

Nov 26th, 2014
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.94 KB | None | 0 0
  1. //
  2. //  NSsocket.cpp
  3. //  PAL
  4. //
  5. //  Created by Erfan on 4/23/14.
  6. //
  7. //
  8.  
  9. #import <Foundation/Foundation.h>
  10. #include "NSsocket.h"
  11. #import "mach/mach.h"
  12. #include <sys/time.h>
  13. #include <netdb.h>
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include "PALcritsec.h"
  17. #include <list>
  18. #include "winEmul.h"
  19.  
  20. #ifdef PHILIPS
  21. #define VERIFY_CERTIFICATE
  22. #endif
  23.  
  24. #ifdef VERIFY_CERTIFICATE
  25. #include <CoreFoundation/CFArray.h>
  26. #include <openssl/ssl.h>
  27. #include <openssl/bio.h>
  28. #include <openssl/x509.h>
  29. #include <openssl/x509_vfy.h>
  30. #include <openssl/pem.h>
  31. #include <openssl/x509v3.h>
  32. #include <openssl/err.h>
  33. #include <openssl/conf.h>
  34. #include <fstream>
  35. #endif
  36.  
  37. #define BUFFER_SIZE 4096
  38.  
  39. @interface NSsocket : NSObject <NSStreamDelegate> {
  40. @private volatile bool m_bConnected;
  41. @private volatile bool m_bHasSpaceAvailable;
  42. #ifdef VERIFY_CERTIFICATE
  43. @private volatile bool m_certificateChecked;
  44. #endif
  45.    
  46. @private NSInputStream *m_pInputStream;
  47. @private NSOutputStream *m_pOutputStream;
  48.    
  49. @private HANDLE m_hSocketError;
  50. @private HANDLE m_hSocketOpened;
  51. @private HANDLE m_hSocketDataReceived;
  52. @private HANDLE m_hSocketClosed;
  53.    
  54. @private PAL::Mutex* m_pReadMutex;
  55. @private PAL::Mutex* m_pWriteMutex;
  56.    
  57. @private std::list<std::string> recvMessageBuffer;
  58. @private std::list<std::string> sendMessageBuffer;
  59. }
  60.  
  61. -(NSStream *)GetStream:(bool)bInput;
  62. -(bool)CreateAndConnect:(const std::string&) serverAddress withPort:(const u_int16_t&) serverPort withTransportMode:(bool)bTLS;
  63. -(void)CloseConnection;
  64. -(void)CloseStreams;
  65. -(void)CloseEvents;
  66. -(bool)IsConnected;
  67. -(int)Send:(const std::string&)sDataToSend;
  68. -(int)Recv:(char *)dataReceived withBufferSize:(int)bufferSize;
  69. -(int)Select:(u_int64_t)uTimeoutValue;
  70. -(void)Signal;
  71.  
  72. @end
  73.  
  74. @implementation NSsocket
  75.  
  76. - (id)init
  77. {
  78.     self = [super init];
  79.     if(self)
  80.     {
  81.         // Must be created at the beginning, otherwise calling Select would cause a crash with NULL events
  82.         m_hSocketError = CreateEvent(NULL, FALSE, FALSE, NULL);
  83.         m_hSocketOpened = CreateEvent(NULL, FALSE, FALSE, NULL);
  84.         m_hSocketDataReceived = CreateEvent(NULL, FALSE, FALSE, NULL);
  85.         m_hSocketClosed = CreateEvent(NULL, FALSE, FALSE, NULL);
  86.        
  87.         m_pReadMutex = new PAL::Mutex;
  88.         m_pWriteMutex = new PAL::Mutex;
  89.     }
  90.    
  91.     return self;
  92. }
  93.  
  94. -(NSStream *)GetStream:(bool)bInput
  95. {
  96.     return bInput ? m_pInputStream : m_pOutputStream;
  97. }
  98.  
  99. -(bool)CreateAndConnect:(const std::string&) serverAddress withPort:(const u_int16_t&) serverPort withTransportMode:(bool)bTLS
  100. {
  101.     NSLog(@"NSStream %p connecting to: %s:%d in %s", self, serverAddress.c_str(), serverPort, bTLS ? "TLS" : "TCP");
  102.    
  103.     CFStringRef remoteHost = CFStringCreateWithCString(kCFAllocatorDefault, serverAddress.c_str(), kCFStringEncodingMacRoman);
  104.    
  105.     CFReadStreamRef readStream;
  106.     CFWriteStreamRef writeStream;
  107.    
  108.     CFStreamCreatePairWithSocketToHost(NULL, remoteHost, serverPort, &readStream, &writeStream);
  109.    
  110. #ifdef VERIFY_CERTIFICATE
  111.     m_certificateChecked = YES;
  112. #endif
  113.    
  114.     // Set options then bridge to ARC:
  115.     if(bTLS)
  116.     {
  117. #ifdef VERIFY_CERTIFICATE
  118.         m_certificateChecked = NO;
  119. #endif
  120.        
  121. #ifndef VERIFY_CERTIFICATE
  122.         NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
  123.                                   (id)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamPropertySocketSecurityLevel,
  124.                                   [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
  125.                                   [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
  126.                                   [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots,
  127.                                   [NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
  128.                                   nil];
  129.        
  130.         CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (__bridge CFDictionaryRef)settings);
  131.         CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (__bridge CFDictionaryRef)settings);
  132. #else
  133.         // Set this kCFStreamPropertySocketSecurityLevel before setting kCFStreamPropertySSLSettings.
  134.         // Setting kCFStreamPropertySocketSecurityLevel appears to override previous settings in kCFStreamPropertySSLSettings
  135.         CFReadStreamSetProperty(readStream,
  136.                                 kCFStreamPropertySocketSecurityLevel,
  137.                                 kCFStreamSocketSecurityLevelNegotiatedSSL);
  138.         // this disables certificate chain validation in ssl settings.
  139.         NSDictionary *sslSettings = [NSDictionary dictionaryWithObjectsAndKeys:
  140.                                      (id)kCFBooleanFalse, (id)kCFStreamSSLValidatesCertificateChain,
  141.                                      nil];
  142.         CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (__bridge CFDictionaryRef)sslSettings);
  143.         CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (__bridge CFDictionaryRef)sslSettings);
  144.        
  145.         CFReadStreamOpen(readStream);
  146.         CFWriteStreamOpen(writeStream);
  147. #endif
  148.     }
  149.    
  150.     CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
  151.     CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
  152.    
  153.     m_pInputStream = (__bridge_transfer NSInputStream *)readStream;
  154.     m_pOutputStream = (__bridge_transfer NSOutputStream *)writeStream;
  155.    
  156.     [m_pInputStream setDelegate:self];
  157.     [m_pOutputStream setDelegate:self];
  158.    
  159.     recvMessageBuffer.clear();
  160.     sendMessageBuffer.clear();
  161.    
  162.     m_bConnected = false;
  163.     m_bHasSpaceAvailable = false;
  164.    
  165.     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
  166.     dispatch_async(queue, ^ {
  167.         // mainRunLoop used instead of currentRunLoop to avoid a crash on Logout
  168.         [m_pInputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
  169.         [m_pOutputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
  170.        
  171.         [m_pInputStream open];
  172.         [m_pOutputStream open];
  173.        
  174.         [[NSRunLoop currentRunLoop] run];
  175.     });
  176.    
  177.     return true;
  178. }
  179.  
  180. -(void)CloseConnection
  181. {
  182.     NSLog(@"NSStream %p closing connection", self);
  183.    
  184.     SetEvent(m_hSocketClosed);
  185.    
  186.     [self CloseStreams];
  187. }
  188.  
  189. -(void)CloseStreams
  190. {
  191.     m_bConnected = false;
  192.    
  193.     [m_pInputStream close];
  194.     [m_pOutputStream close];
  195.     [m_pInputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  196.     [m_pOutputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  197.    
  198.     recvMessageBuffer.clear();
  199.     sendMessageBuffer.clear();
  200. }
  201.  
  202. // Called as the destructor from the CNSsocket's destructor
  203. -(void)CloseEvents
  204. {
  205.     CloseEvent(m_hSocketError);
  206.     CloseEvent(m_hSocketOpened);
  207.     CloseEvent(m_hSocketDataReceived);
  208.     CloseEvent(m_hSocketClosed);
  209.    
  210.     delete m_pReadMutex;
  211.     delete m_pWriteMutex;
  212. }
  213.  
  214. -(bool)IsConnected
  215. {
  216.     return m_bConnected;
  217. }
  218.  
  219. -(int)Send:(const std::string&)sDataToSend
  220. {
  221.     PAL::Critical_Section cs(*m_pWriteMutex);
  222.     int iRet = sDataToSend.length();
  223.     if(m_bHasSpaceAvailable){
  224.         m_bHasSpaceAvailable = false;
  225.         //NSLog(@"NSStream %p sending data of length %lu", self, sDataToSend.length());
  226.         iRet = [m_pOutputStream write:(const uint8_t *)sDataToSend.c_str() maxLength:sDataToSend.length()];
  227.         //NSLog(@"NSStream %p sent length %d", self, iRet);
  228.     }
  229.     else{
  230.         sendMessageBuffer.push_back(sDataToSend);
  231.     }
  232.     return iRet;
  233. }
  234.  
  235. -(int)Recv:(char *)dataReceived withBufferSize:(int)bufferSize
  236. {
  237.     PAL::Critical_Section cs(*m_pReadMutex);
  238.     int dataLength = 0;
  239.     if (recvMessageBuffer.size() > 0)
  240.     {
  241.         std::string buffer = recvMessageBuffer.front();
  242.         recvMessageBuffer.pop_front();
  243.         dataLength = buffer.length() < bufferSize ? buffer.length() : bufferSize;
  244.         memcpy(dataReceived, buffer.c_str(), dataLength);
  245.         // TODO: if buffer.length is greater than bufferSize then the extra data should be stored back so that next time it returns this
  246.     }
  247.    
  248.     if(dataLength == 0 && [m_pInputStream streamStatus] >= NSStreamStatusClosed)
  249.     {
  250.         NSLog(@"NSStream %p recv error", self);
  251.         return -1;
  252.     }
  253.    
  254.     return dataLength;
  255.    
  256. }
  257.  
  258. -(int)Select:(u_int64_t)uTimeoutValue
  259. {
  260.     int iRet = 0;
  261.    
  262.     const int iNumEvents = 4;
  263.    
  264.     HANDLE EventArray[iNumEvents];
  265.     EventArray[0] = m_hSocketError;
  266.     EventArray[1] = m_hSocketOpened;
  267.     EventArray[2] = m_hSocketDataReceived;
  268.     EventArray[3] = m_hSocketClosed;
  269.    
  270.     DWORD dwWaitStatus = WaitForMultipleObjects(iNumEvents, EventArray, FALSE, uTimeoutValue);
  271.    
  272.     switch (dwWaitStatus)
  273.     {
  274.         case WAIT_FAILED:
  275.             break;
  276.            
  277.         case WAIT_OBJECT_0:
  278.             iRet = -1;
  279.             break;
  280.            
  281.         case WAIT_OBJECT_0 + 1:
  282.             iRet = 1;
  283.             break;
  284.            
  285.         case WAIT_OBJECT_0 + 2:
  286.             iRet = 1;
  287.             break;
  288.            
  289.         case WAIT_OBJECT_0 + 3:
  290.             iRet = 0;
  291.             break;
  292.            
  293.         default:
  294.             break;
  295.     }
  296.    
  297.     return iRet;
  298. }
  299.  
  300. -(void)Signal
  301. {
  302.     SetEvent(m_hSocketDataReceived);
  303. }
  304.  
  305. #ifdef VERIFY_CERTIFICATE
  306.  
  307. #define NS_ASSERT(X, ...) \
  308. NSAssert(X, __VA_ARGS__); \
  309. if(!(X)){ \
  310. NSLog(__VA_ARGS__); \
  311. return NO; \
  312. }
  313.  
  314. /*
  315.  * Returns the leaf certificate from a SecTrust object
  316.  * (that is always the certificate at index 0)
  317.  */
  318. static SecCertificateRef SecTrustGetLeafCertificate(SecTrustRef trust)
  319. {
  320.     SecCertificateRef result = NULL;
  321.     if(trust == NULL){
  322.         NSLog(@"trust in null");
  323.         return NULL;
  324.     }
  325.    
  326.     if (SecTrustGetCertificateCount(trust) > 0) {
  327.         result = SecTrustGetCertificateAtIndex(trust, 0);
  328.         if(result == NULL){
  329.             NSLog(@"result in null");
  330.             return NULL;
  331.         }
  332.     }
  333.     return result;
  334. }
  335.  
  336. -(BOOL) VerifyCertificate: (NSStream *)aStream
  337. {
  338.     OpenSSL_add_all_algorithms();
  339.     OpenSSL_add_all_ciphers();
  340.     OpenSSL_add_all_digests();
  341.     ERR_load_BIO_strings();
  342.     ERR_load_crypto_strings();
  343.    
  344.     NSData *certData = nil;
  345.     BOOL result      = NO;
  346.    
  347.     X509 *root_certificate_X509   = NULL;
  348.     X509 *server_certificate_X509 = NULL;
  349.     EVP_PKEY *publicKey           = NULL;
  350.     SecCertificateRef secCertRef  = NULL;
  351.     SecPolicyRef policyRef        = NULL;
  352.     SecTrustRef trustRef          = NULL;
  353.     CFDataRef cfCertRef           = NULL;
  354.     CFArrayRef streamCertRef      = NULL;
  355.    
  356.     NSString *root_certificate_name      = @"philips_trusted_cert";
  357.     NSString *root_certificate_extension = @"der";
  358.     NSString *serverAddrss               = @"www.smartbabymonitor.ugrow.philips.com";
  359.    
  360.     /** Reading root cetificate **/
  361.     NSBundle *bundle = [NSBundle bundleForClass:[self class]];
  362.     certData = [NSData dataWithContentsOfFile:[bundle pathForResource: root_certificate_name ofType: root_certificate_extension]];
  363.     NS_ASSERT(certData != nil, @"certData failed.");
  364.    
  365.     /** root certificate to X509 object **/
  366.     const unsigned char *rootCertificateDataBytes = (const unsigned char *)[certData bytes];
  367.     root_certificate_X509 = d2i_X509(NULL, &rootCertificateDataBytes, [certData length]);
  368.     NS_ASSERT(root_certificate_X509 != NULL, @"root_certificate_X509 failed.");
  369.    
  370.     /** Create Policy **/
  371.     policyRef = SecPolicyCreateSSL(NO, (__bridge CFStringRef) serverAddrss);
  372.     NS_ASSERT(policyRef != NULL, @"policyRef failed.");
  373.    
  374.     /** Create server certificate from stream **/
  375.     streamCertRef = (CFArrayRef)CFBridgingRetain([aStream propertyForKey:(NSString *) kCFStreamPropertySSLPeerCertificates]);
  376.     NS_ASSERT(streamCertRef != NULL, @"streamCertRef failed.");
  377.    
  378.     /** Create Trust **/
  379.     OSStatus status = SecTrustCreateWithCertificates(streamCertRef, policyRef, &trustRef);
  380.     NS_ASSERT(status == errSecSuccess, @"status failed.");
  381.     NS_ASSERT(trustRef != NULL, @"Could not create a trust management object!");
  382.    
  383.     /** intermediate manipulation. certificate ref from trust object and convert into NSData **/
  384.     secCertRef = SecTrustGetLeafCertificate(trustRef);
  385.     NS_ASSERT(secCertRef != NULL, @"secCertRef failed.");
  386.     cfCertRef = SecCertificateCopyData(secCertRef);
  387.     NS_ASSERT(cfCertRef != NULL, @"cfCertRef failed.");
  388.     certData = nil;
  389.     certData = (__bridge NSData *) cfCertRef;
  390.     NS_ASSERT(certData != nil, @"certData failed.");
  391.    
  392.     /** server certificate to X509 object **/
  393.     const unsigned char *serverCertificateDataBytes = (const unsigned char *)[certData bytes];
  394.     server_certificate_X509 = d2i_X509(NULL, &serverCertificateDataBytes, [certData length]);
  395.     NS_ASSERT(server_certificate_X509 != NULL, @"server_certificate_X509 failed.");
  396.    
  397.     /** openSSL certificate verification **/
  398.     publicKey = X509_get_pubkey(root_certificate_X509);
  399.     NS_ASSERT(publicKey != NULL, @"Public Key failed.");
  400.     result = X509_verify(server_certificate_X509, publicKey);
  401.    
  402.     /** releasing memory **/
  403.     EVP_PKEY_free(publicKey);
  404.     X509_free(root_certificate_X509);
  405.     X509_free(server_certificate_X509);
  406.     if(streamCertRef) CFRelease(streamCertRef);
  407.     if(cfCertRef) CFRelease(cfCertRef);
  408.     if(trustRef) CFRelease(trustRef);
  409.     if(policyRef) CFRelease(policyRef);
  410.    
  411.     return result == 1;
  412. }
  413. #endif
  414.  
  415. #pragma mark -
  416. #pragma mark NSStreamDelegate
  417.  
  418. - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
  419. {
  420.     // NSLog(@"NSStream %p eventCode: %d", self, (int)eventCode);
  421.    
  422.     switch (eventCode) {
  423.         case NSStreamEventNone:
  424.             // do nothing.
  425.             //NSLog(@"NSStreamEventNone");
  426.             break;
  427.            
  428.         case NSStreamEventEndEncountered:
  429.             NSLog(@"NSStreamEventEndEncountered %@", [aStream streamError]);
  430.             [self CloseStreams];
  431.             SetEvent(m_hSocketError);
  432.             break;
  433.            
  434.         case NSStreamEventErrorOccurred:
  435.             NSLog(@"NSStreamEventErrorOccurred %@", [aStream streamError]);
  436.             [self CloseStreams];
  437.             SetEvent(m_hSocketError);
  438.             break;
  439.            
  440.         case NSStreamEventHasBytesAvailable:
  441.         {
  442.             if (aStream == m_pInputStream)
  443.             {
  444.                 PAL::Critical_Section cs(*m_pReadMutex);
  445.                 uint8_t buffer[BUFFER_SIZE];
  446.                 NSInteger bytesRead = [m_pInputStream read:buffer maxLength:BUFFER_SIZE];
  447.                
  448.                 //NSLog(@"NSStreamEventHasBytesAvailable of length %d", bytesRead);
  449.                
  450.                 if (0 >= bytesRead)
  451.                     break;
  452.                
  453.                 NSString *nsStringRead = [[NSString alloc] initWithBytes:buffer length:bytesRead encoding:NSUTF8StringEncoding];
  454.                
  455.                 std::string sStringRead = [nsStringRead UTF8String];
  456.                 NSLog(@"recieved data: %s", sStringRead.c_str());
  457.                 recvMessageBuffer.push_back(sStringRead);
  458.                
  459.                 SetEvent(m_hSocketDataReceived);
  460.             }
  461.             break;
  462.         }
  463.         case NSStreamEventHasSpaceAvailable:
  464.         {
  465. #ifdef VERIFY_CERTIFICATE
  466.             if (!m_certificateChecked) {
  467.                 m_certificateChecked = YES;
  468.                 if ([self VerifyCertificate: aStream]) {
  469.                     NSLog(@"Certificate Verification Success.");
  470.                 } else
  471.                 {
  472.                     NSLog(@"Certificate Verification Failed.");
  473.                     [self CloseStreams];
  474.                     SetEvent(m_hSocketError);
  475.                     break;
  476.                 }
  477.             }
  478. #endif
  479.            
  480.             if(aStream == m_pOutputStream)
  481.             {
  482.                 PAL::Critical_Section cs(*m_pWriteMutex);
  483.                 m_bHasSpaceAvailable = true;
  484.                 if(sendMessageBuffer.size() > 0)
  485.                 {
  486.                     std::string sDataToSend = sendMessageBuffer.front();
  487.                     sendMessageBuffer.pop_front();
  488.                     int iWritten = 0;
  489.                     if(sDataToSend.length() > 0)
  490.                     {
  491.                         m_bHasSpaceAvailable = false;
  492.                         //NSLog(@"NSStream %p sending data of length %lu", self, sDataToSend.length());
  493.                         iWritten = [m_pOutputStream write:(const uint8_t *)sDataToSend.c_str() maxLength:sDataToSend.length()];
  494.                         //NSLog(@"NSStream %p sent length %d", self, iWritten);
  495.                     }
  496.                 }
  497.             }
  498.             // SetEvent(m_hSocketOpened);
  499.             break;
  500.         }
  501.         case NSStreamEventOpenCompleted:
  502.             NSLog(@"NSStreamEventOpenCompleted");
  503.             m_bConnected = true;
  504.             //SetEvent(m_hSocketOpened);
  505.             break;
  506.            
  507.         default:
  508.             //NSLog(@"NSStream default");
  509.             break;
  510.     }
  511. }
  512.  
  513. @end
  514.  
  515. /**********************************************************
  516.  CNSsocket implementation
  517.  **********************************************************/
  518.  
  519. CNSsocket::CNSsocket()
  520. {
  521.     m_pNSsocket = [[NSsocket alloc] init];
  522. }
  523.  
  524. CNSsocket::~CNSsocket()
  525. {
  526.     CloseConnection();
  527.     [m_pNSsocket CloseEvents];
  528. }
  529.  
  530. // [TODO] we MUST check the connection status
  531.  
  532. bool CNSsocket::CreateAndConnect(const std::string& serverAddress, const u_int16_t& serverPort, bool bTLS)
  533. {
  534.     return [m_pNSsocket CreateAndConnect:serverAddress withPort:serverPort withTransportMode:bTLS];
  535. }
  536.  
  537. void CNSsocket::GetLocalAddressAndPort(std::string& serverAddress, u_int16_t& serverPort)
  538. {
  539.     CFWriteStreamRef writeStream = (__bridge CFWriteStreamRef) [m_pNSsocket GetStream:false];
  540.    
  541.     // Get the native socket handle:
  542.     CFTypeRef socketTypeRef = CFWriteStreamCopyProperty(writeStream, kCFStreamPropertySocketNativeHandle);
  543.     if(socketTypeRef == NULL)
  544.     {
  545.         NSLog(@"Error in getting native socket handle");
  546.         serverAddress = "";
  547.         serverPort = 0;
  548.        
  549.         return;
  550.     }
  551.    
  552.     CFDataRef socketData = (CFDataRef)socketTypeRef;
  553.     CFSocketNativeHandle socket;
  554.     CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&socket);
  555.    
  556.     // Get the local socket address from the socket handle:
  557.     struct sockaddr_storage sa;
  558.     socklen_t salen = sizeof(sa);
  559.     getsockname(socket, (struct sockaddr *)&sa, &salen);
  560.    
  561.     // Get numeric host and port from socket address:
  562.     char host[NI_MAXHOST];
  563.     char service[NI_MAXSERV];
  564.     getnameinfo((struct sockaddr *)&sa, salen, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST|NI_NUMERICSERV);
  565.    
  566.     serverAddress = std::string(host);
  567.     serverPort = (u_int16_t)atoi(service);
  568.    
  569.     NSLog(@"Local address: %s, local port: %d", serverAddress.c_str(), serverPort);
  570. }
  571.  
  572. void CNSsocket::CloseConnection()
  573. {
  574.     [m_pNSsocket CloseConnection];
  575. }
  576.  
  577. int CNSsocket::Send(const char* dataToSend, int sizeOfData)
  578. {
  579.     return [m_pNSsocket Send:std::string(dataToSend, sizeOfData)];
  580. }
  581.  
  582. int CNSsocket::Recv(char dataReceived[], int bufferSize)
  583. {
  584.     return [m_pNSsocket Recv:dataReceived withBufferSize:bufferSize];
  585. }
  586.  
  587.  
  588. // [TODO] We should use callback instead of select() to reduce processing cost.
  589. // This needs to be called after invoking CreateAndConnect to get connection status.
  590.  
  591. int CNSsocket::Select(u_int64_t timeOutValue)
  592. {
  593.     return [m_pNSsocket Select:timeOutValue];
  594. }
  595.  
  596. int CNSsocket::WaitForConnect(u_int64_t timeOutValue)
  597. {
  598.     u_int64_t slept = 0;
  599.     const u_int64_t duration = 50;
  600.     while(slept < timeOutValue){
  601.         if([m_pNSsocket IsConnected])
  602.             return 1;
  603.         usleep(duration * 1000);
  604.         slept += duration;
  605.     }
  606.     return [m_pNSsocket IsConnected] ? 1 : -1;
  607. }
  608.  
  609. void CNSsocket::Signal()
  610. {
  611.     [m_pNSsocket Signal];
  612. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement