Merge branch 'master' into connectivity-abstraction
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / adapter_util / camsgparser.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include "camsgparser.h"
22 #include "cacommon.h"
23 #include "caadapterutils.h"
24
25 #include <string.h>
26
27 #define CA_MSG_PARSER_TAG "CA_MSG_PARSER"
28
29
30 void printBinaryFormat(char *data)
31 {
32     OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "IN");
33     int i;
34     for (i = 0; i < 8; i++)
35     {
36         OIC_LOG_V(DEBUG, CA_MSG_PARSER_TAG, "c[%d]: %d", i, !!((*data << i) & 0x80));
37     }
38
39     OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "OUT");
40
41 }
42
43 CAResult_t CAGenerateHeader(char *header, uint32_t length)
44 {
45     OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "IN");
46
47     VERIFY_NON_NULL(header, NULL, "header is NULL");
48
49     int temp = 0;
50
51     memset(header, 0x0, sizeof(char) * 2);
52
53     // Set the Header in the first two bits of the data as "01".
54     *header |= 0 << 7;
55     *header |= 1 << 6;
56
57     // Set the NEXT TWO reserved bits to Zero.
58     *header |= 0 << 5;
59     *header |= 0 << 4;
60
61     int i = 0;
62     for (i = 11; i >= 0; i--)
63     {
64         temp = length >> i;
65         if (temp & 1)
66         {
67             if (i > 7)
68             {
69                 *header |= 1 << i - 8;
70             }
71             else
72             {
73                 *(header + 1) |= 1 << i;
74             }
75         }
76         else
77         {
78             if (i > 7)
79             {
80                 *header |= 0 << i - 8 ;
81             }
82             else
83             {
84                 *(header + 1) |= 0 << i;
85             }
86         }
87     }
88
89     OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "OUT");
90
91     return CA_STATUS_OK;
92
93 }
94
95 uint32_t CAParseHeader(const char *header)
96 {
97     OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "IN");
98
99     VERIFY_NON_NULL(header, NULL, "header is NULL");
100
101     int i, j;
102     int dataLen = 0;
103     for (i = 0; i < 8; i++)
104     {
105         int pos = 8 - i;
106         int bit = !!((*header << pos) & 0x80);
107         if ( i >= 4)
108         {
109             if ( 1 == bit)
110             {
111                 dataLen = pow (2, pos + 7) + dataLen;
112             }
113         }
114     }
115
116     for (j = 0; j < 8; j++)
117     {
118         int pos = 7 - j;
119         int bit = !!((*(header + 1) << pos) & 0x80);
120         if ( 1 == bit)
121         {
122             dataLen = pow (2, j) + dataLen;
123         }
124     }
125     return dataLen;
126
127 }
128
129
130 uint32_t CAFragmentData(const char *data, char **dataSegment, uint32_t TotalLen, uint32_t offset)
131 {
132     OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "IN");
133
134     VERIFY_NON_NULL(*data, NULL, "Param data is NULL");
135
136     uint32_t length = 0;
137
138     if (MAX_DATA_LENGTH_SUPPORTED < TotalLen)
139     {
140         OIC_LOG(ERROR, CA_MSG_PARSER_TAG, "dataLen is out of bound");
141         return -1;
142     }
143
144     if ( CA_SUPPORTED_BLE_MTU_SIZE <= TotalLen)
145     {
146         length = CA_SUPPORTED_BLE_MTU_SIZE;
147     }
148     else
149     {
150         length = TotalLen;
151     }
152
153     if (0 == offset)
154     {
155         OIC_LOG_V(DEBUG, CA_MSG_PARSER_TAG, "generatingf the Header info");
156
157         char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
158         VERIFY_NON_NULL_RET(*header, CA_MSG_PARSER_TAG, "Malloc failed", -1);
159
160         *dataSegment = (char *) OICMalloc(sizeof(char) * length);
161         VERIFY_NON_NULL_RET(*dataSegment, CA_MSG_PARSER_TAG, "Malloc failed", -1);
162
163         memset(header, 0x0, sizeof(char) * CA_HEADER_LENGTH );
164         memset(*dataSegment, 0x0, sizeof(char) * length );
165
166         CAResult_t result = CAGenerateHeader(header, TotalLen);
167         if (CA_STATUS_OK != result )
168         {
169             OIC_LOG(ERROR, CA_MSG_PARSER_TAG, "Generate header failed");
170             return -1;
171         }
172
173         memcpy(*dataSegment, header, CA_HEADER_LENGTH);
174         OICFree(header);
175
176         memcpy(*dataSegment + CA_HEADER_LENGTH, data, length - CA_HEADER_LENGTH );
177         return length ;
178     }
179     else
180     {
181         OIC_LOG_V(DEBUG, CA_MSG_PARSER_TAG, "Appending actual data of length [%d]", length);
182
183         *dataSegment = (char *) OICMalloc(sizeof(char) * length);
184         memcpy(*dataSegment, data, length);
185     }
186
187     return length;
188
189 }
190
191 uint32_t CADeFragmentData(const char *datasegment, char **data, uint32_t TotalLen, uint32_t offset)
192 {
193     OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "IN");
194
195     VERIFY_NON_NULL(*data, NULL, "Param data is NULL");
196
197     uint32_t  length = 0;
198
199     memcpy(*data + offset, datasegment, strlen(datasegment));
200
201     length = TotalLen - offset;
202
203     if ( length < 0)
204     {
205         length = 0;
206     }
207
208     OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "OUT");
209
210     return length;
211
212 }
213
214
215