Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
805 - 1
// ///////////////////////////////////////////////////////////////////////////////
2
// Copyright (C) 2010, Frank Blumenberg
3
//
4
// See License.txt for complete licensing and attribution information.
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
11
//
12
// The above copyright notice and this permission notice shall be included in all
13
// copies or substantial portions of the Software.
14
//
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
// THE SOFTWARE.
22
//
23
// ///////////////////////////////////////////////////////////////////////////////
24
 
25
#import "NSData+MKCommandEncode.h"
26
 
27
// ///////////////////////////////////////////////////////////////////////////////
28
#pragma mark Helper funktions
29
 
30
static NSData * encode64(NSData * inData){
31
  unsigned int dstIdx = 0;
32
  unsigned int srcIdx = 0;
33
 
34
  const unsigned char * inBuffer = [inData bytes];
35
  unsigned int length = [inData length];
36
 
37
  unsigned char a, b, c;
38
 
39
  int outDataLength = (length * 4) / 3;
40
 
41
  if (outDataLength % 4)
42
    outDataLength += 4 - (outDataLength % 4);
43
 
44
  NSMutableData * outData = [NSMutableData dataWithLength:outDataLength];
45
 
46
 
47
  char * outBuffer = [outData mutableBytes];
48
 
49
  while (length > 0) {
50
    if (length) {
51
      a = inBuffer[srcIdx++]; length--;
52
    } else a = 0;
53
    if (length) {
54
      b = inBuffer[srcIdx++]; length--;
55
    } else b = 0;
56
    if (length) {
57
      c = inBuffer[srcIdx++]; length--;
58
    } else c = 0;
59
 
60
    outBuffer[dstIdx++] = '=' + (a >> 2);
61
    outBuffer[dstIdx++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
62
    outBuffer[dstIdx++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
63
    outBuffer[dstIdx++] = '=' + ( c & 0x3f);
64
  }
65
 
66
  [outData setLength:dstIdx];
67
 
68
  return outData;
69
}
70
 
71
// ///////////////////////////////////////////////////////////////////////////////
72
 
73
@implementation NSData (MKCommandEncode)
74
 
75
- (NSData *) dataWithCommand:(MKCommandId)aCommand forAddress:(MKAddress)aAddress;
76
{
77
  NSMutableData * frameData = [NSMutableData dataWithLength:3];
78
 
79
  char * frameBytes = [frameData mutableBytes];
80
  frameBytes[0] = '#';
81
  frameBytes[1] = 'a' + aAddress;
82
  frameBytes[2] = aCommand;
83
 
84
  [frameData appendData:encode64(self)];
85
 
86
  NSUInteger frameLength =  [frameData length];
87
  frameBytes = [frameData mutableBytes];
88
 
89
  int crc = 0;
90
  for (int i = 0; i < frameLength; i++) {
91
    crc += frameBytes[i];
92
  }
93
 
94
  crc %= 4096;
95
 
96
  char tmpCrc1 = '=' + (crc / 64);
97
  char tmpCrc2 = ('=' + crc % 64);
98
 
99
  [frameData appendBytes:&tmpCrc1 length:1];
100
  [frameData appendBytes:&tmpCrc2 length:1];
101
  [frameData appendBytes:"\r" length:1];
102
 
103
  return frameData;
104
}
105
 
106
+ (NSData *) dataWithCommand:(MKCommandId)aCommand forAddress:(MKAddress)aAddress payloadForByte:(uint8_t)byte {
107
  NSData * payload = [NSData dataWithBytes:&byte length:1];
108
  return [payload dataWithCommand:aCommand forAddress:aAddress];
109
}
110
 
111
+ (NSData *) dataWithCommand:(MKCommandId)aCommand
112
                  forAddress:(MKAddress)aAddress
113
            payloadWithBytes:(const void *)bytes
114
                      length:(NSUInteger)length {
115
  NSData * payload = [NSData dataWithBytes:bytes length:length];
116
  return [payload dataWithCommand:aCommand forAddress:aAddress];
117
}
118
 
119
@end