Contiki-NG
coap-separate.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  */
31 
32 /**
33  * \file
34  * CoAP module for separate responses.
35  * \author
36  * Matthias Kovatsch <kovatsch@inf.ethz.ch>
37  */
38 
39 /**
40  * \addtogroup coap
41  * @{
42  */
43 
44 #include "coap.h"
45 #include "coap-separate.h"
46 #include "coap-transactions.h"
47 #include "sys/cc.h"
48 #include <string.h>
49 
50 /* Log configuration */
51 #include "coap-log.h"
52 #define LOG_MODULE "coap"
53 #define LOG_LEVEL LOG_LEVEL_COAP
54 
55 /*---------------------------------------------------------------------------*/
56 /*- Separate Response API ---------------------------------------------------*/
57 /*---------------------------------------------------------------------------*/
58 /**
59  * \brief Reject a request that would require a separate response with an error message
60  *
61  * When the server does not have enough resources left to store the information
62  * for a separate response or otherwise cannot execute the resource handler,
63  * this function will respond with 5.03 Service Unavailable. The client can
64  * then retry later.
65  */
66 void
68 {
69  /* TODO: Accept string pointer for custom error message */
70  coap_status_code = SERVICE_UNAVAILABLE_5_03;
71  coap_error_message = "AlreadyInUse";
72 }
73 /*----------------------------------------------------------------------------*/
74 /**
75  * \brief Initiate a separate response with an empty ACK
76  * \param coap_req The request to accept
77  * \param separate_store A pointer to the data structure that will store the
78  * relevant information for the response
79  *
80  * When the server does not have enough resources left to store the information
81  * for a separate response or otherwise cannot execute the resource handler,
82  * this function will respond with 5.03 Service Unavailable. The client can
83  * then retry later.
84  */
85 void
86 coap_separate_accept(coap_message_t *coap_req, coap_separate_t *separate_store)
87 {
88  coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid);
89 
90  LOG_DBG("Separate ACCEPT: /");
91  LOG_DBG_COAP_STRING(coap_req->uri_path, coap_req->uri_path_len);
92  LOG_DBG_(" MID %u\n", coap_req->mid);
93  if(t) {
94  /* send separate ACK for CON */
95  if(coap_req->type == COAP_TYPE_CON) {
96  coap_message_t ack[1];
97  const coap_endpoint_t *ep;
98 
99  ep = coap_get_src_endpoint(coap_req);
100  if(ep == NULL) {
101  LOG_ERR("ERROR: no endpoint in request\n");
102  } else {
103  /* ACK with empty code (0) */
104  coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid);
105  /* serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct */
107  coap_serialize_message(ack, coap_databuf()));
108  }
109  }
110 
111  /* store remote endpoint address */
112  coap_endpoint_copy(&separate_store->endpoint, &t->endpoint);
113 
114  /* store correct response type */
115  separate_store->type =
116  coap_req->type == COAP_TYPE_CON ? COAP_TYPE_CON : COAP_TYPE_NON;
117  separate_store->mid = coap_get_mid(); /* if it was a NON, we burned one MID in the engine... */
118 
119  memcpy(separate_store->token, coap_req->token, coap_req->token_len);
120  separate_store->token_len = coap_req->token_len;
121 
122  separate_store->block1_num = coap_req->block1_num;
123  separate_store->block1_size = coap_req->block1_size;
124 
125  separate_store->block2_num = coap_req->block2_num;
126  separate_store->block2_size = coap_req->block2_size > 0 ? MIN(COAP_MAX_BLOCK_SIZE, coap_req->block2_size) : COAP_MAX_BLOCK_SIZE;
127 
128  /* signal the engine to skip automatic response and clear transaction by engine */
129  coap_status_code = MANUAL_RESPONSE;
130  } else {
131  LOG_ERR("ERROR: Response transaction for separate request not found!\n");
132  coap_status_code = INTERNAL_SERVER_ERROR_5_00;
133  }
134 }
135 /*----------------------------------------------------------------------------*/
136 void
137 coap_separate_resume(coap_message_t *response, coap_separate_t *separate_store,
138  uint8_t code)
139 {
140  coap_init_message(response, separate_store->type, code,
141  separate_store->mid);
142  if(separate_store->token_len) {
143  coap_set_token(response, separate_store->token,
144  separate_store->token_len);
145  }
146  if(separate_store->block1_size) {
147  coap_set_header_block1(response, separate_store->block1_num,
148  0, separate_store->block1_size);
149  }
150 }
151 /*---------------------------------------------------------------------------*/
152 /** @} */
Log support for CoAP
void coap_separate_accept(coap_message_t *coap_req, coap_separate_t *separate_store)
Initiate a separate response with an empty ACK.
Definition: coap-separate.c:86
CoAP module for separate responses.
int coap_sendto(const coap_endpoint_t *ep, const uint8_t *data, uint16_t len)
Send a message to the specified CoAP endpoint.
Definition: coap-uip.c:369
void coap_endpoint_copy(coap_endpoint_t *dest, const coap_endpoint_t *src)
Copy a CoAP endpoint from one memory area to another.
Definition: coap-uip.c:154
uint8_t * coap_databuf(void)
Returns a common data buffer that can be used when generating CoAP messages for transmission.
Definition: coap-uip.c:322
CoAP module for reliable transport
An implementation of the Constrained Application Protocol (RFC 7252).
Default definitions of C compiler quirk work-arounds.
void coap_separate_reject()
Reject a request that would require a separate response with an error message.
Definition: coap-separate.c:67