Wired Networking  2.0
Objective-C implementation of the Wired 2.0 protocol
WIP7Socket.m
00001 /* $Id$ */
00002 
00003 /*
00004  *  Copyright (c) 2008-2009 Axel Andersson
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *  1. Redistributions of source code must retain the above copyright
00011  *     notice, this list of conditions and the following disclaimer.
00012  *  2. Redistributions in binary form must reproduce the above copyright
00013  *     notice, this list of conditions and the following disclaimer in the
00014  *     documentation and/or other materials provided with the distribution.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00017  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
00020  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00023  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00024  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00025  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026  * POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 // ugly !!!
00030 #define WI_RSA 1
00031 
00032 #import <WiredNetworking/NSString-WINetworking.h>
00033 #import <WiredNetworking/WIError.h>
00034 #import <WiredNetworking/WIP7Message.h>
00035 #import <WiredNetworking/WIP7Socket.h>
00036 #import <WiredNetworking/WIP7Spec.h>
00037 #import <WiredNetworking/WISocket.h>
00038 
00039 static void _WIP7SocketReadMessage(wi_p7_socket_t *, wi_p7_message_t *, void *);
00040 static void _WIP7SocketWroteMessage(wi_p7_socket_t *, wi_p7_message_t *, void *);
00041 
00042 
00043 static void _WIP7SocketReadMessage(wi_p7_socket_t *p7Socket, wi_p7_message_t *p7Message, void *contextInfo) {
00044                 [[(id) contextInfo delegate] P7Socket:contextInfo readMessage:[WIP7Message messageWithMessage:p7Message spec:[(id) contextInfo spec]]];
00045 }
00046 
00047 
00048 
00049 static void _WIP7SocketWroteMessage(wi_p7_socket_t *p7Socket, wi_p7_message_t *p7Message, void *contextInfo) {
00050                 [[(id) contextInfo delegate] P7Socket:contextInfo wroteMessage:[WIP7Message messageWithMessage:p7Message spec:[(id) contextInfo spec]]];
00051 }
00052 
00053 
00054 
00055 @interface WIP7Socket(Private)
00056 
00057 - (WIError *)_errorWithCode:(NSInteger)code;
00058 
00059 @end
00060 
00061 
00062 @implementation WIP7Socket(Private)
00063 
00064 - (WIError *)_errorWithCode:(NSInteger)code {
00065                 return [WIError errorWithDomain:WIWiredNetworkingErrorDomain
00066                                                                                                                    code:code
00067                                                                                                    userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
00068                                                                                                                                                  [WIError errorWithDomain:WILibWiredErrorDomain],
00069                                                                                                                                                                  WILibWiredErrorKey,
00070                                                                                                                                                  [[_socket address] string],
00071                                                                                                                                                                  WIArgumentErrorKey,
00072                                                                                                                                                  NULL]];
00073 }
00074 
00075 @end
00076 
00077 
00078 
00079 @implementation WIP7Socket
00080 
00081 + (void)initialize {
00082 //              wi_p7_socket_debug = true;
00083 }
00084 
00085 
00086 
00087 #pragma mark -
00088 
00089 - (id)initWithSocket:(WISocket *)socket spec:(WIP7Spec *)spec {
00090                 self = [super init];
00091                 
00092                 _socket                         = [socket retain];
00093                 _spec                           = [spec retain];
00094                 
00095                 _p7Socket = wi_p7_socket_init_with_socket(wi_p7_socket_alloc(), [_socket socket], [_spec spec]);
00096                 
00097                 return self;
00098 }
00099 
00100 
00101 
00102 - (void)dealloc {
00103                 [_socket release];
00104                 [_spec release];
00105                 
00106                 [_readTimeoutError release];
00107                 
00108                 wi_release(_p7Socket);
00109                 
00110                 [super dealloc];
00111 }
00112 
00113 
00114 
00115 #pragma mark -
00116 
00117 - (void)setDelegate:(id)aDelegate {
00118                 delegate = aDelegate;
00119                 
00120                 if([delegate respondsToSelector:@selector(P7Socket:readMessage:)])
00121                    wi_p7_socket_set_read_message_callback(_p7Socket, _WIP7SocketReadMessage, self);
00122                 else
00123                                 wi_p7_socket_set_read_message_callback(_p7Socket, NULL, NULL);
00124 
00125                 if([delegate respondsToSelector:@selector(P7Socket:wroteMessage:)])
00126                                 wi_p7_socket_set_wrote_message_callback(_p7Socket, _WIP7SocketWroteMessage, self);
00127                 else
00128                                 wi_p7_socket_set_wrote_message_callback(_p7Socket, NULL, NULL);
00129 }
00130 
00131 
00132 
00133 - (id)delegate {
00134                 return delegate;
00135 }
00136 
00137 
00138 
00139 #pragma mark -
00140 
00141 - (WISocket *)socket {
00142                 return _socket;
00143 }
00144 
00145 
00146 
00147 - (wi_p7_socket_t *)P7Socket {
00148                 return _p7Socket;
00149 }
00150 
00151 
00152 
00153 - (WIP7Spec *)spec {
00154                 return _spec;
00155 }
00156 
00157 
00158 
00159 - (NSUInteger)options {
00160                 return wi_p7_socket_options(_p7Socket);
00161 }
00162 
00163 
00164 
00165 - (WIP7Serialization)serialization {
00166                 return wi_p7_socket_serialization(_p7Socket);
00167 }
00168 
00169 
00170 
00171 - (NSString *)remoteProtocolName {
00172                 return [NSString stringWithWiredString:wi_p7_socket_remote_protocol_name(_p7Socket)];
00173 }
00174 
00175 
00176 
00177 - (NSString *)remoteProtocolVersion {
00178                 return [NSString stringWithWiredString:wi_p7_socket_remote_protocol_version(_p7Socket)];
00179 }
00180 
00181 
00182 
00183 - (BOOL)usesEncryption {
00184                 return WI_P7_ENCRYPTION_ENABLED([self options]);
00185 }
00186 
00187 
00188 
00189 - (NSString *)cipherName {
00190     
00191 #ifdef WI_RSA
00192                 wi_cipher_t                     *cipher;
00193                 cipher = wi_p7_socket_cipher(_p7Socket);
00194                 
00195                 return cipher ? [NSString stringWithWiredString:wi_cipher_name(cipher)] : NULL;
00196 #else
00197                 return NULL;
00198 #endif
00199 }
00200 
00201 
00202 
00203 - (NSUInteger)cipherBits {
00204 #ifdef WI_RSA
00205                 wi_cipher_t                     *cipher;
00206                 
00207                 cipher = wi_p7_socket_cipher(_p7Socket);
00208                 
00209                 return cipher ? wi_cipher_bits(cipher) : 0;
00210 #else
00211                 return 0;
00212 #endif
00213 }
00214 
00215 
00216 
00217 - (BOOL)usesCompression {
00218                 return WI_P7_COMPRESSION_ENABLED([self options]);
00219 }
00220 
00221 
00222 
00223 - (double)compressionRatio {
00224                 return wi_p7_socket_compression_ratio(_p7Socket);
00225 }
00226 
00227 
00228 
00229 #pragma mark -
00230 
00231 - (BOOL)verifyMessage:(WIP7Message *)message error:(WIError **)error {
00232                 wi_pool_t                       *pool;
00233                 wi_boolean_t    result;
00234                 
00235                 pool = wi_pool_init(wi_pool_alloc());
00236                 result = wi_p7_socket_verify_message(_p7Socket, [message message]);
00237                 wi_release(pool);
00238                 
00239                 if(!result) {
00240                                 if(error)
00241                                                 *error = [WIError errorWithDomain:WILibWiredErrorDomain];
00242                                 
00243                                 return NO;
00244                 }
00245                 
00246                 return YES;
00247 }
00248 
00249 
00250 
00251 #pragma mark -
00252 
00253 - (BOOL)connectWithOptions:(NSUInteger)options serialization:(WIP7Serialization)serialization username:(NSString *)username password:(NSString *)password timeout:(NSTimeInterval)timeout error:(WIError **)error {
00254                 wi_pool_t                       *pool;
00255                 wi_boolean_t    result;
00256                 
00257                 pool = wi_pool_init(wi_pool_alloc());
00258                 result = wi_p7_socket_connect(_p7Socket, timeout, options, serialization, [username wiredString], [password wiredString]);
00259                 wi_release(pool);
00260 
00261                 if(!result) {
00262                                 if(error)
00263                                                 *error = [self _errorWithCode:WISocketConnectFailed];
00264                                 
00265                                 return NO;
00266                 }
00267                 
00268                 return YES;
00269 }
00270 
00271 
00272 
00273 - (BOOL)acceptWithOptions:(NSUInteger)options timeout:(NSTimeInterval)timeout error:(WIError **)error {
00274                 wi_pool_t                       *pool;
00275                 wi_boolean_t    result;
00276                 
00277                 pool = wi_pool_init(wi_pool_alloc());
00278                 result = wi_p7_socket_accept(_p7Socket, timeout, options);
00279                 wi_release(pool);
00280                 
00281                 if(!result) {
00282                                 if(error)
00283                                                 *error = [self _errorWithCode:WISocketConnectFailed];
00284                                 
00285                                 return NO;
00286                 }
00287                 
00288                 return YES;
00289 }
00290 
00291 
00292 
00293 - (void)close {
00294                 wi_p7_socket_close(_p7Socket);
00295 }
00296 
00297 
00298 
00299 #pragma mark -
00300 
00301 - (BOOL)writeMessage:(WIP7Message *)message timeout:(NSTimeInterval)timeout error:(WIError **)error {
00302                 wi_pool_t                                       *pool;
00303                 wi_boolean_t                    result;
00304                 
00305                 pool = wi_pool_init(wi_pool_alloc());
00306                 result = wi_p7_socket_write_message(_p7Socket, timeout, [message message]);
00307                 wi_release(pool);
00308                 
00309                 if(!result) {
00310                                 if(error)
00311                                                 *error = [self _errorWithCode:WISocketWriteFailed];
00312                                 
00313                                 return NO;
00314                 }
00315                 
00316                 return YES;
00317 }
00318 
00319 
00320 
00321 - (WIP7Message *)readMessageWithTimeout:(NSTimeInterval)timeout error:(WIError **)error {
00322                 wi_pool_t                                       *pool;
00323                 wi_p7_message_t                 *result;
00324                 WIP7Message                                     *message;
00325                 
00326                 pool = wi_pool_init(wi_pool_alloc());
00327                 result = wi_p7_socket_read_message(_p7Socket, timeout);
00328                 
00329                 if(!result) {
00330                                 if(error) {
00331                                                 if(wi_error_domain() == WI_ERROR_DOMAIN_ERRNO && wi_error_code() == ETIMEDOUT) {
00332                                                                 if(!_readTimeoutError)
00333                                                                                 _readTimeoutError = [[self _errorWithCode:WISocketReadFailed] retain];
00334                                                                 
00335                                                                 *error = _readTimeoutError;
00336                                                 } else {
00337                                                                 *error = [self _errorWithCode:WISocketReadFailed];
00338                                                 }
00339                                 }
00340                                 
00341                                 wi_release(pool);
00342                                 
00343                                 return NULL;
00344                 }
00345                 
00346                 message = [WIP7Message messageWithMessage:result spec:_spec];
00347                 
00348                 wi_release(pool);
00349                 
00350                 return message;
00351 }
00352 
00353 
00354 
00355 - (BOOL)writeOOBData:(const void *)data length:(NSUInteger)length timeout:(NSTimeInterval)timeout error:(WIError **)error {
00356                 wi_boolean_t                    result;
00357                 
00358                 result = wi_p7_socket_write_oobdata(_p7Socket, timeout, data, length);
00359 
00360                 if(!result) {
00361                                 if(error)
00362                                                 *error = [self _errorWithCode:WISocketWriteFailed];
00363                                 
00364                                 return NO;
00365                 }
00366                 
00367                 return YES;
00368 }
00369 
00370 
00371 
00372 - (NSInteger)readOOBData:(void **)data timeout:(NSTimeInterval)timeout error:(WIError **)error {
00373                 wi_integer_t                    result;
00374                 
00375                 result = wi_p7_socket_read_oobdata(_p7Socket, timeout, data);
00376                 
00377                 if(result < 0) {
00378                                                 if(wi_error_domain() == WI_ERROR_DOMAIN_ERRNO && wi_error_code() == ETIMEDOUT) {
00379                                                                 if(!_readTimeoutError)
00380                                                                                 _readTimeoutError = [[self _errorWithCode:WISocketReadFailed] retain];
00381                                                                 
00382                                                                 *error = _readTimeoutError;
00383                                                 } else {
00384                                                                 *error = [self _errorWithCode:WISocketReadFailed];
00385                                                 }
00386                                 
00387                                 return result;
00388                 }
00389                 
00390                 return result;
00391 }
00392 
00393 @end
 All Classes