RSS

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

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

« back to all changes in this revision

Viewing changes to tappity/source/TappityClient.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
//  TappityClient.m
 
3
//  tappity
 
4
//
 
5
//  Created by döme on 25.10.2009.
 
6
//  Copyright 2009 __MyCompanyName__. All rights reserved.
 
7
//
 
8
 
 
9
#import "TappityClient.h"
 
10
#import "Tappity.h"
 
11
 
 
12
#import <sys/types.h>
 
13
#include <sys/socket.h>
 
14
#include <netdb.h>
 
15
#include <netinet/in.h>
 
16
#include <sys/time.h>
 
17
 
 
18
@implementation TappityClient
 
19
 
 
20
- (void) runThreadWithSelector: (SEL) selector
 
21
{
 
22
        @synchronized(self)
 
23
        {
 
24
                if (!activeThreads)
 
25
                        activeThreads = [[NSMutableDictionary alloc] init];
 
26
                id number = [NSNumber numberWithInt: threadIds++];
 
27
 
 
28
                [activeThreads setObject: [NSNumber numberWithBool: YES] forKey: number];
 
29
                [NSThread detachNewThreadSelector: selector toTarget: self withObject: [number retain]];
 
30
        }
 
31
}
 
32
 
 
33
 
 
34
- (void) connectToService: (NSNetService*) service
 
35
{
 
36
        NSInteger       port = [service port];
 
37
        NSString*       hostName = [service hostName];
 
38
        
 
39
        NSLog(@"tappity attempting to connect to %@ : %d", hostName, port);
 
40
 
 
41
        int sockfd = 0;
 
42
 
 
43
 
 
44
//      _setStandardSocketOpts(socket);
 
45
 
 
46
        struct addrinfo hints, *servinfo = NULL, *p = NULL;
 
47
        int rv = 0;
 
48
 
 
49
        memset(&hints, 0, sizeof hints);
 
50
        hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
 
51
        hints.ai_socktype = SOCK_STREAM;
 
52
        //hints.ai_protocol = IPPROTO_TCP;
 
53
        hints.ai_flags    = AI_PASSIVE;
 
54
        
 
55
//      NSHost* host = [NSHost hostWithName: hostName];
 
56
 
 
57
        if ((rv = getaddrinfo([hostName UTF8String], [[NSString stringWithFormat: @"%d", port] UTF8String], &hints, &servinfo)) != 0)
 
58
        {
 
59
                fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
 
60
                exit(1);
 
61
        }
 
62
 
 
63
        // loop through all the results and connect to the first we can
 
64
        for(p = servinfo; p != NULL; p = p->ai_next)
 
65
        {
 
66
                if ((sockfd = socket(p->ai_family, p->ai_socktype,
 
67
                                p->ai_protocol)) == -1) {
 
68
                        perror("socket");
 
69
                        continue;
 
70
                }
 
71
 
 
72
                if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
 
73
                        close(sockfd);
 
74
                        perror("connect");
 
75
                        continue;
 
76
                }
 
77
 
 
78
                break; // if we get here, we must have connected successfully
 
79
        }
 
80
 
 
81
        if (p == NULL) {
 
82
                // looped off the end of the list with no connection
 
83
                fprintf(stderr, "failed to connect\n");
 
84
                exit(2);
 
85
        }
 
86
 
 
87
        freeaddrinfo(servinfo); // all done with this structure
 
88
 
 
89
        NSLog(@"tappity connected");
 
90
 
 
91
 
 
92
        self->commsSocket = sockfd;
 
93
        
 
94
        if (!sendLock)
 
95
                sendLock = [[NSCondition alloc] init];
 
96
        
 
97
        [self runThreadWithSelector: @selector(sendingThread:)];
 
98
        
 
99
 
 
100
 
 
101
}
 
102
 
 
103
- (void) sendTapData: (NSData*) tapData
 
104
{               
 
105
        [sendLock lock];
 
106
 
 
107
        if (!sendQueue)
 
108
                sendQueue = [[NSMutableArray alloc] init];
 
109
 
 
110
        [sendQueue addObject: tapData];
 
111
        
 
112
        [sendLock signal];
 
113
        [sendLock unlock];
 
114
                
 
115
}
 
116
 
 
117
 
 
118
- (void) recordApplicationEvent: (NSDictionary*) event
 
119
{
 
120
//      NSLog(@"%@", event);
 
121
        NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: kTapRecordedEvent], TapIdKey, event, TapRecordedEventKey, nil];
 
122
 
 
123
        NSData* data = [NSPropertyListSerialization dataFromPropertyList: dict format: NSPropertyListBinaryFormat_v1_0 errorDescription: nil];
 
124
        assert(data);
 
125
        [self sendTapData: data];
 
126
}
 
127
 
 
128
 
 
129
 
 
130
- (BOOL) threadActive: (id) key
 
131
{
 
132
        return [[activeThreads objectForKey: key] boolValue];
 
133
}
 
134
 
 
135
 
 
136
- (void) sendingThread: (id) info
 
137
{
 
138
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
139
 
 
140
        @synchronized(self)
 
141
        {
 
142
                [self retain];
 
143
        }
 
144
 
 
145
        while ([self threadActive: info])
 
146
        {
 
147
                [sendLock lock];
 
148
                        while (![sendQueue count])
 
149
                                [sendLock wait];
 
150
                                
 
151
                NSLog(@"sending tap");
 
152
                
 
153
                NSData* data = [[sendQueue objectAtIndex: 0] retain];
 
154
                [sendQueue removeObjectAtIndex: 0];
 
155
                
 
156
                size_t sizeToSend = 4;
 
157
                size_t dataSent = 0;
 
158
                uint32_t header = htonl([data length]);
 
159
                int err = 0;
 
160
 
 
161
                while (dataSent < sizeToSend)
 
162
                {
 
163
                        if ((err = send(commsSocket, &header + dataSent, sizeToSend - dataSent, 0)) == -1)
 
164
                        {
 
165
                                perror("send");
 
166
                        //      break;
 
167
                        }
 
168
                        else
 
169
                                dataSent += err;
 
170
                }
 
171
                
 
172
                sizeToSend = [data length];
 
173
                dataSent = 0;
 
174
                while (dataSent < sizeToSend)
 
175
                {
 
176
                        if ((err = send(commsSocket, [data bytes] + dataSent, sizeToSend - dataSent, 0)) == -1)
 
177
                        {
 
178
                                perror("send");
 
179
                        //      break;
 
180
                        }
 
181
                        else
 
182
                                dataSent += err;
 
183
                                
 
184
                }
 
185
                
 
186
                [data release];
 
187
                
 
188
                [sendLock unlock];
 
189
                
 
190
        }
 
191
 
 
192
        @synchronized(self)
 
193
        {
 
194
                [self release];
 
195
        }
 
196
 
 
197
        [info release];
 
198
        [pool drain];
 
199
}
 
200
 
 
201
static size_t _write_i8(void* buf, uint8_t val)
 
202
{
 
203
        memcpy(buf, &val, 1);
 
204
        return 1;
 
205
}
 
206
 
 
207
static size_t _write_i16(void* buf, uint16_t val)
 
208
{
 
209
        val = CFSwapInt16HostToBig(val);
 
210
        memcpy(buf, &val, 2);
 
211
        return 2;
 
212
}
 
213
 
 
214
static size_t _write_i32(void* buf, uint32_t val)
 
215
{
 
216
        val = CFSwapInt32HostToBig(val);
 
217
        memcpy(buf, &val, 4);
 
218
        return 4;
 
219
}
 
220
 
 
221
static size_t _write_i64(void* buf, uint64_t val)
 
222
{
 
223
        val = CFSwapInt64HostToBig(val);
 
224
        memcpy(buf, &val, 8);
 
225
        return 8;
 
226
}
 
227
 
 
228
static size_t _write_float(void* buf, float val)
 
229
{
 
230
        CFSwappedFloat32 v = CFConvertFloat32HostToSwapped(val);
 
231
        memcpy(buf, &v, 4);
 
232
        return 4;
 
233
}
 
234
 
 
235
static size_t _write_gspoint(void* buf, GSTouchPointRef p)
 
236
{
 
237
        size_t bc = 0;
 
238
 
 
239
        bc += _write_i32(buf+bc, p->unk0);
 
240
        bc += _write_float(buf+bc, p->unk1);
 
241
        bc += _write_float(buf+bc, p->touchSize);
 
242
        bc += _write_float(buf+bc, p->x);
 
243
        bc += _write_float(buf+bc, p->y);
 
244
        bc += _write_i32(buf+bc, (uint32_t)p->window);
 
245
        
 
246
        return bc;
 
247
}
 
248
 
 
249
/*
 
250
- (id) plistWithTouches: (NSSet*) touches
 
251
{
 
252
        NSMutableArray* ary = [NSMutableArray array];
 
253
        
 
254
        for (UITouch* touch in touches)
 
255
        {
 
256
                NSMutableData* tdata = [NSMutableData dataWithLength: sizeof(UITouch)];
 
257
                size_t bc = 0;
 
258
                void* buf = [tdata mutableBytes];
 
259
                bc += _write_double(buf+bc, touch->_timestamp);
 
260
                
 
261
        }
 
262
        
 
263
        return ary;
 
264
}
 
265
*/
 
266
 
 
267
- (void) sendTouch: (UIEvent*) event inPhase: (int) phase
 
268
{
 
269
        return;
 
270
        NSMutableDictionary* touchDict = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: kTapTouchEvent], TapIdKey, nil];
 
271
 
 
272
//      [touchDict setObject: [self touchesAsPlist: [event allTouches]] forKey: TapTouchesKey];
 
273
 
 
274
        GSEvent* gse = [event _gsEvent];
 
275
 
 
276
        NSMutableData* gsData = [NSMutableData dataWithLength: sizeof(GSEvent)];
 
277
        size_t bc = 0;
 
278
        void* buf = [gsData mutableBytes];
 
279
        
 
280
        bc += _write_i32(buf + bc, gse->type0);
 
281
        bc += _write_i32(buf + bc, gse->type1);
 
282
        bc += _write_i32(buf + bc, gse->r3);
 
283
        bc += _write_float(buf + bc, gse->avgX0);
 
284
        bc += _write_float(buf + bc, gse->avgY0);
 
285
        bc += _write_float(buf + bc, gse->avgX1);
 
286
        bc += _write_float(buf + bc, gse->avgY1);
 
287
        bc += _write_i32(buf + bc, gse->processId);
 
288
        bc += _write_i64(buf + bc, gse->timestamp);
 
289
        bc += _write_i32(buf + bc, (uint32_t)gse->window);
 
290
        bc += _write_i32(buf + bc, gse->r11);
 
291
        bc += _write_i32(buf + bc, gse->type12);
 
292
        bc += _write_i32(buf + bc, gse->gesture13);
 
293
        bc += _write_i32(buf + bc, gse->gesture14);
 
294
        bc += _write_i16(buf + bc, gse->numInitialTouches);
 
295
        bc += _write_i16(buf + bc, gse->numCurrentTouches);
 
296
        bc += _write_i32(buf + bc, gse->r16);
 
297
        bc += _write_i32(buf + bc, gse->r17);
 
298
        bc += _write_i32(buf + bc, gse->r18);
 
299
        bc += _write_i32(buf + bc, gse->r19);
 
300
        bc += _write_i32(buf + bc, gse->r20);
 
301
        bc += _write_i32(buf + bc, gse->r21);
 
302
        bc += _write_i8(buf + bc, gse->r22_0);
 
303
        bc += _write_i8(buf + bc, gse->numPoints);
 
304
        bc += _write_i8(buf + bc, gse->r22_2);
 
305
        for (size_t i = 0; i < gse->numPoints; ++i)
 
306
                bc += _write_gspoint(buf+bc, gse->points+i);
 
307
 
 
308
        [touchDict setObject: gsData forKey: TapGSEventKey];
 
309
        [touchDict setObject: [NSNumber numberWithInt: phase] forKey: TapTouchPhaseKey];
 
310
        //[touchDict setObject: [self plistWithTouches: [event allTouches]] forKey: TapTouchesKey];
 
311
 
 
312
        NSData* data = [NSPropertyListSerialization dataFromPropertyList: touchDict format: NSPropertyListBinaryFormat_v1_0 errorDescription: nil];
 
313
        assert(data);
 
314
        [self sendTapData: data];
 
315
 
 
316
}
 
317
 
 
318
- (void) dealloc
 
319
{
 
320
        [currentData release];
 
321
        [sendQueue release];
 
322
        [activeThreads release];
 
323
        close(commsSocket);
 
324
 
 
325
        [super dealloc];
 
326
}
 
327
 
 
328
 
 
329
@end

Loggerhead 1.17 is a web-based interface for Bazaar branches