blob: eaa6c36e7d75d4e8ad12e7d4db688046104e95fd [file] [log] [blame]
/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "coap_connection.h"
CoapPDU *create_connection(uint8_t type, const char * const server, const char * const endpoint, int port, const CoapMessage * const message) {
CoapPDU *pdu = (CoapPDU*) malloc(sizeof(CoapPDU));
pdu->ctx = NULL;
pdu->session = NULL;
coap_uri_t uri;
uri.host.s = (uint8_t*) server; // may be a loss in resolution, but hostnames should be char *
uri.host.length = strlen(server);
uri.path.s = (uint8_t*) endpoint; // ^ same as above for paths.
uri.path.length = strlen(endpoint);
uri.port = port;
uri.scheme = COAP_URI_SCHEME_COAP;
fd_set readfds;
coap_pdu_t* request;
unsigned char get_method = 1;
int res = resolve_address(&uri.host, &pdu->dst_addr.addr.sa);
if (res < 0) {
return NULL;
}
pdu->dst_addr.size = res;
pdu->dst_addr.addr.sin.sin_port = htons(uri.port);
void *addrptr = NULL;
char port_str[NI_MAXSERV] = "0";
switch (pdu->dst_addr.addr.sa.sa_family) {
case AF_INET:
addrptr = &pdu->dst_addr.addr.sin.sin_addr;
if (!create_session(&pdu->ctx, &pdu->session, 0x00, port_str, &pdu->dst_addr)) {
break;
} else {
return NULL;
}
case AF_INET6:
addrptr = &pdu->dst_addr.addr.sin6.sin6_addr;
if (!create_session(&pdu->ctx, &pdu->session, 0x00, port_str, &pdu->dst_addr)) {
break;
} else {
return NULL;
}
default:
;
}
// we want to register handlers in the event that an error occurs or nack is returned
// from the library
coap_register_event_handler(pdu->ctx, coap_event);
coap_register_nack_handler(pdu->ctx, no_acknowledgement);
coap_context_set_keepalive(pdu->ctx, 1);
coap_str_const_t pld;
pld.length = message->size_;
pld.s = message->data_;
coap_register_option(pdu->ctx, COAP_OPTION_BLOCK2);
// set the response handler
coap_register_response_handler(pdu->ctx, response_handler);
pdu->session->max_retransmit = 1;
pdu->optlist = NULL;
// add the URI option to the options list
coap_insert_optlist(&pdu->optlist, coap_new_optlist(COAP_OPTION_URI_PATH, uri.path.length, uri.path.s));
// next, create the PDU.
if (!(request = create_request(pdu->ctx, pdu->session, &pdu->optlist, type, &pld)))
return NULL;
// send the PDU using the session.
coap_send(pdu->session, request);
return pdu;
}
int8_t send_pdu(const CoapPDU * const pdu) {
uint64_t wait_ms = 1 * 200;
// run once will attempt to send the first time
int runResponse = coap_run_once(pdu->ctx, wait_ms);
// if no data is received, we will attempt re-transmission
// until the number of attempts has been reached.
while (!coap_can_exit(pdu->ctx)) {
runResponse = coap_run_once(pdu->ctx, wait_ms);
}
if (runResponse < 0)
return -1;
else
return 0;
}
int8_t free_pdu(CoapPDU * pdu) {
if (NULL == pdu) {
return -1;
}
coap_delete_optlist(pdu->optlist);
coap_session_release(pdu->session);
coap_free_context(pdu->ctx);
free(pdu);
return 0;
}