Subversion Repositories Projects

Rev

Go to most recent revision | 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+MKCommandDecode.h"
26
 
27
#define kInvalidMKCommand @"Invalid MK command"
28
 
29
// ///////////////////////////////////////////////////////////////////////////////
30
#pragma mark Helper funktions
31
 
32
static NSData * decode64(const char * inBuffer, int length)
33
{
34
  unsigned char a, b, c, d;
35
  unsigned char x, y, z;
36
 
37
  int srcIdx = 0;
38
  int dstIdx = 0;
39
 
40
  NSMutableData * outData = [NSMutableData dataWithLength:length];
41
  unsigned char * outBuffer = [outData mutableBytes];
42
 
43
  if (inBuffer[srcIdx] != 0)
44
  {
45
    while (length != 0)
46
    {
47
      a = inBuffer[srcIdx++] - '=';
48
      b = inBuffer[srcIdx++] - '=';
49
      c = inBuffer[srcIdx++] - '=';
50
      d = inBuffer[srcIdx++] - '=';
51
 
52
      x = (a << 2) | (b >> 4);
53
      y = ((b & 0x0f) << 4) | (c >> 2);
54
      z = ((c & 0x03) << 6) | d;
55
 
56
      if (length--) outBuffer[dstIdx++] = x; else break;
57
      if (length--) outBuffer[dstIdx++] = y; else break;
58
      if (length--) outBuffer[dstIdx++] = z; else break;
59
    }
60
  }
61
 
62
  [outData setLength:dstIdx];
63
  return outData;
64
}
65
 
66
// ///////////////////////////////////////////////////////////////////////////////
67
@implementation NSData (MKCommandDecode)
68
 
69
- (NSUInteger) frameLength;
70
{
71
  NSUInteger frameLength =  [self length];
72
  const char * frameBytes = [self bytes];
73
 
74
  if (frameLength > 0 && frameBytes[frameLength - 1] == '\r')
75
    frameLength--;
76
 
77
  return frameLength;
78
}
79
 
80
 
81
- (BOOL) isMkData
82
{
83
  NSUInteger frameLength =  [self frameLength];
84
  const char * frameBytes = [self bytes];
85
 
86
  if ( frameLength < 5)
87
  {
88
    NSLog(@"The frame length is to short %d. Frame is invalid", frameLength);
89
    return NO;
90
  }
91
 
92
  if (frameBytes[0] != '#')
93
  {
94
    NSLog(@"The frame is no MK frame");
95
    return NO;
96
  }
97
 
98
  return YES;
99
}
100
 
101
 
102
- (BOOL) isCrcOk
103
{
104
 
105
  if (![self isMkData])
106
    return NO;
107
 
108
  NSUInteger frameLength =  [self frameLength];
109
  const uint8_t * frameBytes = [self bytes];
110
 
111
  uint8_t crc2 = frameBytes[frameLength - 1];
112
  uint8_t crc1 = frameBytes[frameLength - 2];
113
 
114
  int crc = 0;
115
  for (int i = 0; i < frameLength - 2; i++)
116
  {
117
    crc += frameBytes[i];
118
  }
119
 
120
  crc %= 4096;
121
 
122
  if (crc1 == ('=' + (crc / 64)) && crc2 == ('=' + crc % 64))
123
    return YES;
124
 
125
  return NO;
126
}
127
 
128
- (MKAddress) address
129
{
130
  if (![self isCrcOk])
131
    [NSException raise:kInvalidMKCommand format:@"cannot get the address from a invalid MK frame"];
132
 
133
  const char * frameBytes = [self bytes];
134
 
135
  return (MKAddress)(frameBytes[1] - 'a');
136
}
137
 
138
- (MKCommandId) command
139
{
140
  if (![self isCrcOk])
141
    [NSException raise:kInvalidMKCommand format:@"cannot get the address from a invalid MK frame"];
142
 
143
  const char * frameBytes = [self bytes];
144
  return frameBytes[2];
145
}
146
 
147
 
148
- (NSData *) payload;
149
{
150
  NSUInteger frameLength =  [self frameLength];
151
  const char * frameBytes = [self bytes];
152
 
153
  int startIndex = 3;
154
  int frameDataLength = frameLength - startIndex - 2;
155
 
156
  return decode64(frameBytes + startIndex, frameDataLength);
157
}
158
 
159
 
160
@end