RSS

(root)/iphone/tappity : 46 : tappity/source/TappityServer.m

To get this branch, use:
bzr branch /browse/iphone/tappity

« back to all changes in this revision

Viewing changes to tappity/source/TappityServer.m

Dömötör Gulyás
2009-10-27 01:03:19
Revision ID: dognotdog@gmail.com-20091027000319-1vrkixkgf9lkud6g
adds tappity project

Show diffs side-by-side

added added

removed removed

 
1
//
 
2
//  TappityServer.m
 
3
//  Jigs
 
4
//
 
5
//  Created by döme on 25.10.2009.
 
6
//  Copyright 2009 __MyCompanyName__. All rights reserved.
 
7
//
 
8
 
 
9
#import "TappityServer.h"
 
10
#import "Tappity.h"
 
11
 
 
12
 
 
13
static void _setStandardSocketOpts(int socket)
 
14
{
 
15
    int yes = 1;
 
16
    setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
 
17
        int timeout = 2000;
 
18
        setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));
 
19
        setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
 
20
}
 
21
 
 
22
@interface UIApplication (TappityPrivate)
 
23
- (void)_playbackEvents:(id)arg1 atPlaybackRate:(float)arg2 messageWhenDone:(id)arg3 withSelector:(SEL)arg4;
 
24
@end
 
25
 
 
26
@implementation TappityServer
 
27
 
 
28
- (BOOL) threadActive: (id) key
 
29
{
 
30
        return [[activeThreads objectForKey: key] boolValue];
 
31
}
 
32
 
 
33
- (void) receivingThread: (id) info
 
34
{
 
35
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
36
 
 
37
        @synchronized(self)
 
38
        {
 
39
                [self retain];
 
40
        }
 
41
 
 
42
        while ([self threadActive: info])
 
43
        {
 
44
                struct timeval tv;
 
45
                fd_set readfds;
 
46
                fd_set writefds;
 
47
                fd_set errorfds;
 
48
                int maxSocket = -1;
 
49
 
 
50
                tv.tv_sec = 1;
 
51
                tv.tv_usec = 0;
 
52
 
 
53
                FD_ZERO(&readfds);
 
54
                FD_ZERO(&writefds);
 
55
                FD_ZERO(&errorfds);
 
56
 
 
57
                FD_SET(commsSocket, &readfds);
 
58
                FD_SET(commsSocket, &errorfds);
 
59
                maxSocket = MAX(maxSocket, commsSocket);
 
60
                
 
61
                if (maxSocket < 0)
 
62
                {
 
63
                        //printf("No sockets, sleeping for a bit...\n");
 
64
                        usleep(1000000);
 
65
                        continue;
 
66
                }
 
67
 
 
68
                if (select(maxSocket+1, &readfds, &writefds, &errorfds, &tv) < 0)
 
69
                {
 
70
                        perror("select");
 
71
                        break;
 
72
                }
 
73
 
 
74
                if (FD_ISSET(commsSocket, &readfds))
 
75
                {
 
76
                        NSLog(@"receiving...");
 
77
                        if (!expectedMessageSize)
 
78
                        {
 
79
                                uint32_t buf = 0;
 
80
                                int actuallyRead = 0;
 
81
                        
 
82
                                actuallyRead = recv(commsSocket, &buf, sizeof(uint32_t), MSG_PEEK);
 
83
                                
 
84
                                if (actuallyRead == sizeof(uint32_t))
 
85
                                {
 
86
                                        actuallyRead = recv(commsSocket, &buf, sizeof(uint32_t), 0);
 
87
                                        expectedMessageSize = ntohl(buf);
 
88
                                        currentData = [[NSMutableData alloc] initWithLength: expectedMessageSize];
 
89
                                }
 
90
                                else if (!actuallyRead)
 
91
                                {
 
92
                                        // close this socket as nothing read means connection closed
 
93
                                        close(commsSocket);
 
94
                                        self->commsSocket = 0;
 
95
                                        printf("Connection dropped.\n");
 
96
                                        break;
 
97
                                }
 
98
                                if (actuallyRead == -1)
 
99
                                {
 
100
                                        close(commsSocket);
 
101
                                        self->commsSocket = 0;
 
102
                                        printf("Connection dropped with error.\n");
 
103
                                        break;
 
104
                                }
 
105
                        }
 
106
                        else
 
107
                        {
 
108
                                size_t readAmount = expectedMessageSize - currentlyRead;
 
109
                                int actuallyRead = 0;
 
110
                        
 
111
                                actuallyRead = recv(commsSocket, [currentData mutableBytes] + currentlyRead, readAmount, 0);
 
112
                                if (actuallyRead == -1)
 
113
                                {
 
114
                                        close(commsSocket);
 
115
                                        self->commsSocket = 0;
 
116
                                        printf("Connection dropped with error.\n");
 
117
                                        break;
 
118
                                }
 
119
                                currentlyRead += actuallyRead;
 
120
                                
 
121
                                if (currentlyRead == expectedMessageSize)
 
122
                                {
 
123
                                        @synchronized(self)
 
124
                                        {
 
125
                                                expectedMessageSize = 0;
 
126
                                                /*
 
127
                                                if (!receivedPackets)
 
128
                                                        receivedPackets = [[NSMutableArray alloc] init];
 
129
                                                [receivedPackets addObject: currentData];
 
130
                                                [currentData release];
 
131
                                                */
 
132
                                                
 
133
                                        }
 
134
                                        [self performSelectorOnMainThread: @selector(tapReceived:) withObject: currentData waitUntilDone: NO];
 
135
                                        currentData = nil;
 
136
                                        currentlyRead = 0;
 
137
                                }
 
138
                        }
 
139
 
 
140
                }
 
141
        }
 
142
 
 
143
        @synchronized(self)
 
144
        {
 
145
                [self release];
 
146
        }
 
147
 
 
148
        [info release];
 
149
        [pool drain];
 
150
}
 
151
 
 
152
 
 
153
- (void) runThreadWithSelector: (SEL) selector
 
154
{
 
155
        @synchronized(self)
 
156
        {
 
157
                if (!activeThreads)
 
158
                        activeThreads = [[NSMutableDictionary alloc] init];
 
159
                id number = [NSNumber numberWithInt: threadIds++];
 
160
 
 
161
                [activeThreads setObject: [NSNumber numberWithBool: YES] forKey: number];
 
162
                [NSThread detachNewThreadSelector: selector toTarget: self withObject: [number retain]];
 
163
        }
 
164
}
 
165
 
 
166
- (void) acceptThread: (id) info
 
167
{
 
168
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
169
 
 
170
        @synchronized(self)
 
171
        {
 
172
                [self retain];
 
173
        }
 
174
 
 
175
        while ([self threadActive: info])
 
176
        {
 
177
 
 
178
                struct timeval tv;
 
179
                fd_set readfds;
 
180
                fd_set writefds;
 
181
                fd_set errorfds;
 
182
                int maxSocket = -1;
 
183
 
 
184
                tv.tv_sec = 1;
 
185
                tv.tv_usec = 0;
 
186
 
 
187
                FD_ZERO(&readfds);
 
188
                FD_ZERO(&writefds);
 
189
                FD_ZERO(&errorfds);
 
190
 
 
191
                FD_SET(listenSocket, &readfds);
 
192
                FD_SET(listenSocket, &errorfds);
 
193
                maxSocket = MAX(maxSocket, listenSocket);
 
194
                
 
195
                if (maxSocket < 0)
 
196
                {
 
197
                        printf("No sockets, sleeping for a bit...\n");
 
198
                        usleep(1000000);
 
199
                        continue;
 
200
                }
 
201
                
 
202
                //NSLog(@"listening for connection...");
 
203
 
 
204
                if (select(maxSocket+1, &readfds, &writefds, &errorfds, &tv) < 0)
 
205
                {
 
206
                        perror("select");
 
207
                        break;
 
208
                }
 
209
 
 
210
                if (FD_ISSET(listenSocket, &readfds))
 
211
                {
 
212
                        NSLog(@"Accepting connection...");
 
213
                        // accept
 
214
                        socklen_t       sinSize = sizeof(struct sockaddr_in);
 
215
                        struct sockaddr_in      peerAddress;
 
216
                        int newSocket = accept(listenSocket, (struct sockaddr *)&peerAddress, &sinSize);
 
217
                        
 
218
                        _setStandardSocketOpts(newSocket);
 
219
 
 
220
                        
 
221
                        if (newSocket == -1)
 
222
                        {
 
223
                                if (errno == EWOULDBLOCK)
 
224
                                {
 
225
                                }
 
226
                                else
 
227
                                {
 
228
                                        printf("Error accepting connection.\n");
 
229
                                        break;
 
230
                                }
 
231
                        }
 
232
                        
 
233
                        if (commsSocket)
 
234
                                close(commsSocket);
 
235
 
 
236
                        // add socket to sockets list
 
237
                        commsSocket = newSocket;
 
238
                        
 
239
                        
 
240
                        [self runThreadWithSelector: @selector(receivingThread:)];
 
241
                        
 
242
                        NSLog(@"Accepted connection.");
 
243
                }
 
244
 
 
245
        }
 
246
 
 
247
        @synchronized(self)
 
248
        {
 
249
                [self release];
 
250
        }
 
251
 
 
252
        [info release];
 
253
        [pool drain];
 
254
}
 
255
 
 
256
- (BOOL) enableBonjourWithDomain:(NSString*)domain applicationProtocol:(NSString*)protocol name:(NSString*)name
 
257
{
 
258
        if(![domain length])
 
259
                domain = @""; //Will use default Bonjour registration doamins, typically just ".local"
 
260
        if(![name length])
 
261
                name = @""; //Will use default Bonjour name, e.g. the name assigned to the device in iTunes
 
262
        
 
263
        assert([protocol length] && listenSocket);
 
264
        
 
265
        NSLog(@"tappity port: %d", ntohs(myAddress.sin_port));
 
266
 
 
267
        netService = [[NSNetService alloc] initWithDomain: domain type: protocol name: name port: ntohs(myAddress.sin_port)];
 
268
        if(netService == nil)
 
269
                return NO;
 
270
        
 
271
        [netService setDelegate:self];
 
272
//      [netService scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
 
273
        [netService publish];
 
274
        
 
275
        return YES;
 
276
}
 
277
 
 
278
- (void) start
 
279
{
 
280
        NSLog(@"starting tappity server");
 
281
        myAddress.sin_family = AF_INET;                                 // host byte order
 
282
        myAddress.sin_port = htons(1234);                               // short, network byte order, any port
 
283
        myAddress.sin_addr.s_addr = htonl(INADDR_ANY);  // auto-fill with my IP
 
284
 
 
285
        listenSocket = socket(PF_INET, SOCK_STREAM, 0);
 
286
        assert(listenSocket != -1);
 
287
 
 
288
        _setStandardSocketOpts(listenSocket);
 
289
 
 
290
        int err = bind(self->listenSocket, (struct sockaddr *)&myAddress, sizeof(myAddress));
 
291
        assert(-1 != err);
 
292
        
 
293
        err = listen(self->listenSocket, 1);
 
294
        assert(-1 != err);
 
295
 
 
296
        [self runThreadWithSelector: @selector(acceptThread:)];
 
297
        
 
298
        if([self enableBonjourWithDomain: @"" applicationProtocol: @"_tappity._tcp" name: @"tappity"])
 
299
                NSLog(@"tappity bounjour advertisments up and running");
 
300
 
 
301
}
 
302
 
 
303
static size_t _read_i8(const void* buf, uint8_t* p)
 
304
{
 
305
        uint8_t v = 0;
 
306
        memcpy(&v, buf, 1);
 
307
        *p = v;
 
308
        return 1;
 
309
}
 
310
static size_t _read_i16(const void* buf, uint16_t* p)
 
311
{
 
312
        uint16_t v = 0;
 
313
        memcpy(&v, buf, 2);
 
314
        *p = CFSwapInt16BigToHost(v);
 
315
        return 2;
 
316
}
 
317
static size_t _read_i32(const void* buf, uint32_t* p)
 
318
{
 
319
        uint32_t v = 0;
 
320
        memcpy(&v, buf, 4);
 
321
        *p = CFSwapInt32BigToHost(v);
 
322
        return 4;
 
323
}
 
324
static size_t _read_i64(const void* buf, uint64_t* p)
 
325
{
 
326
        uint64_t v = 0;
 
327
        memcpy(&v, buf, 8);
 
328
        *p = CFSwapInt64BigToHost(v);
 
329
        return 8;
 
330
}
 
331
static size_t _read_float(const void* buf, float* p)
 
332
{
 
333
        CFSwappedFloat32 v;
 
334
        memcpy(&v, buf, 4);
 
335
        *p = CFConvertFloat32SwappedToHost(v);
 
336
        return 4;
 
337
}
 
338
 
 
339
static size_t _read_gspoint(const void* buf, GSTouchPointRef p)
 
340
{
 
341
        size_t bc = 0;
 
342
 
 
343
        bc += _read_i32(buf+bc, &p->unk0);
 
344
        bc += _read_float(buf+bc, &p->unk1);
 
345
        bc += _read_float(buf+bc, &p->touchSize);
 
346
        bc += _read_float(buf+bc, &p->x);
 
347
        bc += _read_float(buf+bc, &p->y);
 
348
        bc += _read_i32(buf+bc, (uint32_t*)&p->window);
 
349
        
 
350
        return bc;
 
351
}
 
352
 
 
353
- (GSEvent*) gsEventWithData: (NSData*) data
 
354
{
 
355
        GSEvent* gse = [[[GSEvent alloc] init] autorelease];
 
356
        
 
357
        size_t bc = 0;
 
358
        const void* buf = [data bytes];
 
359
        
 
360
        bc += _read_i32(buf+bc, &gse->type0);
 
361
        bc += _read_i32(buf+bc, &gse->type1);
 
362
        bc += _read_i32(buf+bc, &gse->r3);
 
363
        bc += _read_float(buf+bc, &gse->avgX0);
 
364
        bc += _read_float(buf+bc, &gse->avgY0);
 
365
        bc += _read_float(buf+bc, &gse->avgX1);
 
366
        bc += _read_float(buf+bc, &gse->avgY1);
 
367
        bc += _read_i32(buf+bc, &gse->processId);
 
368
        bc += _read_i64(buf+bc, &gse->timestamp);
 
369
        bc += _read_i32(buf+bc, (uint32_t*)&gse->window);
 
370
        bc += _read_i32(buf+bc, &gse->r11);
 
371
        bc += _read_i32(buf+bc, &gse->type12);
 
372
        bc += _read_i32(buf+bc, &gse->gesture13);
 
373
        bc += _read_i32(buf+bc, &gse->gesture14);
 
374
        bc += _read_i16(buf+bc, &gse->numInitialTouches);
 
375
        bc += _read_i16(buf+bc, &gse->numCurrentTouches);
 
376
        bc += _read_i32(buf+bc, &gse->r16);
 
377
        bc += _read_i32(buf+bc, &gse->r17);
 
378
        bc += _read_i32(buf+bc, &gse->r18);
 
379
        bc += _read_i32(buf+bc, &gse->r19);
 
380
        bc += _read_i32(buf+bc, &gse->r20);
 
381
        bc += _read_i32(buf+bc, &gse->r21);
 
382
        bc += _read_i8(buf+bc, &gse->r22_0);
 
383
        bc += _read_i8(buf+bc, &gse->numPoints);
 
384
        bc += _read_i16(buf+bc, &gse->r22_2);
 
385
        for (size_t i = 0; i < gse->numPoints; ++i)
 
386
                bc += _read_gspoint(buf+bc, gse->points + i);
 
387
 
 
388
        return gse;
 
389
}
 
390
 
 
391
- (void) tapReceived: (NSData*) tapData
 
392
{
 
393
        assert([tapData length] > 4);
 
394
        
 
395
        
 
396
        NSDictionary* tapDict = [NSPropertyListSerialization propertyListFromData: tapData mutabilityOption:NSPropertyListImmutable format: NULL errorDescription: NULL];
 
397
        assert(tapDict);
 
398
        switch([[tapDict objectForKey: TapIdKey] intValue])
 
399
        {
 
400
                case kTapTouchEvent:
 
401
                {
 
402
                        NSLog(@"TOUCH EVENT");
 
403
                        
 
404
                        GSEvent* gse = [self gsEventWithData: [tapDict objectForKey: TapGSEventKey]];
 
405
                        UIWindow* window = [[UIApplication sharedApplication] keyWindow];
 
406
                        gse->window = window;
 
407
                        for (size_t i = 0; i < gse->numPoints; ++i)
 
408
                                gse->points[i].window = window;
 
409
                        
 
410
                        int phase = [[tapDict objectForKey: TapTouchPhaseKey] intValue];
 
411
                        NSSet* touches = [UITouch _createTouchesWithGSEvent: gse phase: phase view: [[UIApplication sharedApplication] keyWindow]];
 
412
                        
 
413
                        assert([[UIApplication sharedApplication] keyWindow]);
 
414
                        
 
415
                        NSLog(@"%@", touches);
 
416
 
 
417
                        UIEvent* event = [UIEvent alloc];
 
418
                        
 
419
                        Class touchesEventClass = objc_getClass("UITouchesEvent");
 
420
                        if (touchesEventClass && ![[event class] isEqual: touchesEventClass])
 
421
                        {
 
422
                                event = [touchesEventClass alloc];
 
423
                        }
 
424
                        
 
425
                        [event _initWithEvent: gse touches: touches];
 
426
                        
 
427
                        assert(event);
 
428
                        
 
429
                        [[UIApplication sharedApplication] sendEvent: event];
 
430
                                                
 
431
                        
 
432
                        break;
 
433
                }
 
434
                case kTapRecordedEvent:
 
435
                {
 
436
                        NSLog(@"RECORDED EVENT");
 
437
                        
 
438
                        NSDictionary* eventDict = [tapDict objectForKey: TapRecordedEventKey];
 
439
                        
 
440
                        [[UIApplication sharedApplication] _playbackEvents:[NSArray arrayWithObject: eventDict] atPlaybackRate: 1.0f messageWhenDone: nil withSelector: nil];
 
441
 
 
442
                        break;
 
443
                }
 
444
        }
 
445
        
 
446
}
 
447
 
 
448
 
 
449
/*
 
450
- (void)performTouches: (NSSet*) touches inView: (UIView *)view
 
451
{
 
452
    UITouch *touch = [[UITouch alloc] initInView:view];
 
453
    UIEvent *eventDown = [[UIEvent alloc] initWithTouch:touch];
 
454
    
 
455
    [touch.view touchesBegan:[eventDown allTouches] withEvent:eventDown];
 
456
    
 
457
    [touch setPhase:UITouchPhaseEnded];
 
458
    UIEvent *eventUp = [[UIEvent alloc] initWithTouch:touch];
 
459
    
 
460
    [touch.view touchesEnded:[eventUp allTouches] withEvent:eventUp];
 
461
    
 
462
    [eventDown release];
 
463
    [eventUp release];
 
464
    [touch release];
 
465
}
 
466
*/
 
467
 
 
468
- (void) dealloc
 
469
{
 
470
        
 
471
        [netService stop];
 
472
        [netService release];
 
473
 
 
474
        [activeThreads release];
 
475
 
 
476
        [super dealloc];
 
477
}
 
478
 
 
479
@end

Loggerhead 1.17 is a web-based interface for Bazaar branches