1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
25 #include "caprotocolmessage.h"
27 #include "oic_malloc.h"
31 #define CA_MAX_TOKEN_LEN 8
32 #define CA_FLAGS_BLOCK 0x01
33 #define CA_URI_MAX_SIZE 256
36 uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t* outReqInfo)
38 OIC_LOG(DEBUG, TAG, "get request info from PDU");
42 uint32_t code = CA_NOT_FOUND;
43 CAGetRequestPDUInfo(pdu, &code, &(outReqInfo->info));
44 outReqInfo->method = code;
48 uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t* outResInfo)
50 OIC_LOG(DEBUG, TAG, "get response info from PDU");
54 uint32_t code = CA_NOT_FOUND;
55 CAGetRequestPDUInfo(pdu, &code, &(outResInfo->info));
56 outResInfo->result = code;
61 coap_pdu_t* CAGeneratePdu(const char* uri, const uint32_t code, const CAInfo_t info)
63 OIC_LOG(DEBUG, TAG, "generate PDU");
67 uint32_t coapHeaderLength = 12;
69 coap_list_t *optlist = NULL;
75 coapUri = (char*) OICMalloc(length + coapHeaderLength + 1);
76 memset(coapUri, 0, length + coapHeaderLength + 1);
81 memcpy(coapUri, "coap://[::]/", coapHeaderLength);
82 memcpy(coapUri + coapHeaderLength, uri, length);
84 // parsing options in URI
85 CAParseURI(coapUri, &optlist);
87 // parsing options in HeadOption
90 CAParseHeadOption(code, info, &optlist);
96 if (NULL != info.payload)
98 if (!(pdu = CACreatePDUforRequestWithPayload((code_t) code, optlist, info.payload)))
103 if (!(pdu = CACreatePDUforRequest((code_t) code, optlist)))
107 // pdu print method : coap_show_pdu(pdu);
112 coap_pdu_t* CAParsePDU(const char* data, uint32_t* outCode)
114 coap_pdu_t* outpdu = coap_new_pdu();
115 coap_pdu_parse((unsigned char *) data, strlen(data), outpdu);
116 (*outCode) = (uint32_t) outpdu->hdr->code;
121 coap_pdu_t* CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *options,
124 OIC_LOG(DEBUG, TAG, "CACreatePDUforRequestWithPayload");
128 unsigned char _token_data[8];
132 if (!(pdu = coap_new_pdu()))
135 /* initialize message id */
136 unsigned short message_id;
137 prng((unsigned char *)&message_id, sizeof(unsigned short));
139 pdu->hdr->type = msgtype;
140 pdu->hdr->id = htons(++message_id);
141 pdu->hdr->code = code;
143 pdu->hdr->token_length = the_token.length;
144 if (!coap_add_token(pdu, the_token.length, the_token.s))
146 OIC_LOG(DEBUG, TAG,"cannot add token to request");
149 for (opt = options; opt; opt = opt->next)
151 coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *)opt->data),
152 COAP_OPTION_LENGTH(*(coap_option *)opt->data),
153 COAP_OPTION_DATA(*(coap_option *)opt->data));
158 uint32_t len = strlen(payload);
159 if ((flags & CA_FLAGS_BLOCK) == 0)
161 OIC_LOG_V(DEBUG, TAG, "coap_add_data, payload: %s", payload);
162 coap_add_data(pdu, len, payload);
166 OIC_LOG_V(DEBUG, TAG, "coap_add_block, payload: %s", payload);
167 coap_add_block(pdu, len, payload, block.num, block.szx);
173 coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options)
175 OIC_LOG(DEBUG, TAG, "CACreatePDUforRequest");
179 unsigned char _token_data[8];
183 if (!(pdu = coap_new_pdu()))
186 /* initialize message id */
187 unsigned short message_id;
188 prng((unsigned char *)&message_id, sizeof(unsigned short));
190 pdu->hdr->type = msgtype;
191 pdu->hdr->id = htons(++message_id);
192 pdu->hdr->code = code;
194 pdu->hdr->token_length = the_token.length;
195 if (!coap_add_token(pdu, the_token.length, the_token.s))
197 OIC_LOG(DEBUG, TAG, "cannot add token to request");
200 for (opt = options; opt; opt = opt->next)
202 coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *)opt->data),
203 COAP_OPTION_LENGTH(*(coap_option *)opt->data),
204 COAP_OPTION_DATA(*(coap_option *)opt->data));
210 void CAParseURI(const char* uriInfo, coap_list_t **optlist)
212 OIC_LOG(DEBUG, TAG, "parse URI");
214 unsigned char portbuf[2];
215 unsigned char _buf[CA_BUFSIZE];
216 unsigned char *buf = _buf;
221 OIC_LOG_V(DEBUG, TAG, "url : %s", uriInfo);
223 /* split arg into Uri-* options */
224 coap_split_uri((unsigned char *) uriInfo, strlen(uriInfo), &uri);
226 if (uri.port != COAP_DEFAULT_PORT)
229 CACreateNewOptionNode(COAP_OPTION_URI_PORT,
230 coap_encode_var_bytes(portbuf, uri.port), portbuf), CAOrderOpts);
236 res = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
241 CACreateNewOptionNode(COAP_OPTION_URI_PATH, COAP_OPT_LENGTH(buf),
242 COAP_OPT_VALUE(buf)), CAOrderOpts);
243 buf += COAP_OPT_SIZE(buf);
247 if (uri.query.length)
251 res = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);
256 CACreateNewOptionNode(COAP_OPTION_URI_QUERY, COAP_OPT_LENGTH(buf),
257 COAP_OPT_VALUE(buf)), CAOrderOpts);
259 buf += COAP_OPT_SIZE(buf);
265 void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist)
267 OIC_LOG_V(DEBUG, TAG, "start parse Head Option : %d", info.numOptions);
270 for (i = 0; i < info.numOptions; i++)
273 CACreateNewOptionNode(info.options->optionID, info.options->optionLength,
274 info.options->optionData), CAOrderOpts);
278 coap_list_t* CACreateNewOptionNode(const uint16_t key, const uint32_t length, const uint8_t *data)
283 option = coap_malloc(sizeof(coap_option) + length);
287 COAP_OPTION_KEY(*option) = key;
288 COAP_OPTION_LENGTH(*option) = length;
289 memcpy(COAP_OPTION_DATA(*option), data, length);
291 /* we can pass NULL here as delete function since option is released automatically */
292 node = coap_new_listnode(option, NULL);
297 error: perror("new_option_node: malloc");
302 int32_t CAOrderOpts(void *a, void *b)
305 return a < b ? -1 : 1;
307 if (COAP_OPTION_KEY(*(coap_option *)a) < COAP_OPTION_KEY(*(coap_option *)b))
310 return COAP_OPTION_KEY(*(coap_option *)a) == COAP_OPTION_KEY(*(coap_option *)b);
313 void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t* outCode, CAInfo_t* outInfo)
315 unsigned char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */
317 coap_opt_iterator_t opt_iter;
319 char optionResult[CA_URI_MAX_SIZE] =
322 uint32_t isfirstsetflag = 0;
324 /* show options, if any */
325 coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL);
327 memset(optionResult, 0, sizeof(optionResult));
328 while ((option = coap_option_next(&opt_iter)))
331 if (print_readable(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option), buf, sizeof(buf),
334 if (opt_iter.type == COAP_OPTION_URI_PATH || opt_iter.type == COAP_OPTION_URI_QUERY)
336 if (0 == isfirstsetflag)
339 memcpy(optionResult + count, buf, strlen(buf));
340 count += strlen(buf);
345 if (opt_iter.type == COAP_OPTION_URI_PATH)
347 memcpy(optionResult + count, "/", 1);
350 else if (opt_iter.type == COAP_OPTION_URI_QUERY)
352 memcpy(optionResult + count, "?", 1);
355 memcpy(optionResult + count, buf, strlen(buf));
356 count += strlen(buf);
362 OIC_LOG(DEBUG, TAG, "set CAInfo_t after parsing");
365 (*outCode) = (uint32_t) pdu->hdr->code;
366 memset(outInfo, 0, sizeof(CAInfo_t));
368 outInfo->options = (CAHeaderOption_t*) OICMalloc(sizeof(CAHeaderOption_t));
369 memset(outInfo->options, 0, sizeof(CAHeaderOption_t));
371 outInfo->options->optionID = opt_iter.type;
372 outInfo->options->optionLength = count;
373 memcpy(outInfo->options->optionData, optionResult, CA_MAX_HEADER_OPTION_DATA_LENGTH);
375 if (pdu->hdr->token_length > 0)
377 outInfo->token = (char*) OICMalloc(pdu->hdr->token_length);
378 memcpy(outInfo->token, pdu->hdr->token, pdu->hdr->token_length);
381 if (NULL != pdu->data)
383 outInfo->payload = (char*) OICMalloc(strlen(pdu->data) + 1);
384 memcpy(outInfo->payload, pdu->data, strlen(pdu->data) + 1);
388 CAResult_t CAGenerateTokenInternal(CAToken_t* token)
390 OIC_LOG(DEBUG, TAG, "generate the token");
395 void CADestroyTokenInternal(CAToken_t token)
397 OIC_LOG(DEBUG, TAG, "destroy the token!!");