Exemplo n.º 1
0
/*
 * Function:    _wilddog_coap_send.
 * Description: send out and coap package.
 *   
 * Input:       p_coap : point to an coap package.
 * Output:      N/A.
 * Return:      Wilddog_Return_T type.
*/
Wilddog_Return_T WD_SYSTEM _wilddog_coap_send(void *p_arg,int flag)
{
    coap_pdu_t *p_coap = (coap_pdu_t*)p_arg;
    
    if( p_coap == NULL)
        return WILDDOG_ERR_INVALID;
    
#ifdef DEBUG_LEVEL
    if(DEBUG_LEVEL <= WD_DEBUG_LOG )
        coap_show_pdu(p_coap);
#endif
   return _wilddog_sec_send(p_coap->hdr, p_coap->length);
}
Exemplo n.º 2
0
// When we receive the CoAP response we build and send the HTTP response
void coap_response_handler(struct coap_context_t *ctx, const coap_endpoint_t *local_interface,
                           const coap_address_t *remote, coap_pdu_t *sent, coap_pdu_t *received, const coap_tid_t id) {
    printf("COAP %13s:%-5u -> ",
           inet_ntoa((&remote->addr.sin)->sin_addr),
           ntohs((&remote->addr.sin)->sin_port));
    coap_show_pdu(received);

    for(int i = 0; i < MAX_HTTP_CONNECTIONS; i++) {
        if(http_coap_pairs[i].message_id == received->hdr->id) {
            struct MHD_Connection *connection = http_coap_pairs[i].connection;
            size_t len = 0;
            unsigned char *databuf = NULL;

            struct MHD_Response *response = MHD_create_response_from_buffer(len, databuf, MHD_RESPMEM_MUST_COPY);

            int read_result = coap_get_data(received, &len, &databuf);
            if(received->hdr->code == COAP_RESPONSE_CODE(205) && read_result == 0) {
                coap_abort_to_http(connection, "coap_get_data: cannot read CoAP response data\n");
            }

            static char tid_str[8];
            snprintf(tid_str, sizeof(tid_str), "%u", ntohs(received->hdr->id));
            MHD_add_response_header(response, "X-CoAP-Message-Id", tid_str);
            MHD_add_response_header(response, "X-CoAP-Response-Code", msg_code_string(received->hdr->code));

            // HTTP Content-Type
            const char *http_content_type;
            int coap_content_format;
            coap_opt_iterator_t opt_iter;
            coap_opt_t *option;
            coap_option_iterator_init(received, &opt_iter, COAP_OPT_ALL);
            while((option = coap_option_next(&opt_iter))) {
                switch(opt_iter.type) {
                    case COAP_OPTION_CONTENT_FORMAT:
                        coap_content_format = (int)coap_decode_var_bytes(COAP_OPT_VALUE(option),
                                                                         COAP_OPT_LENGTH(option));
                        break;
                    default:
                        continue;
                }
            }
            switch(coap_content_format) {
                case COAP_MEDIATYPE_TEXT_PLAIN:                 http_content_type = "text/plain"; break;
                case COAP_MEDIATYPE_APPLICATION_LINK_FORMAT:    http_content_type = "application/link-format"; break;
                case COAP_MEDIATYPE_APPLICATION_XML:            http_content_type = "application/xml"; break;
                case COAP_MEDIATYPE_APPLICATION_OCTET_STREAM:   http_content_type = "application/octet-stream"; break;
                case COAP_MEDIATYPE_APPLICATION_EXI:            http_content_type = "application/exi"; break;
                case COAP_MEDIATYPE_APPLICATION_JSON:           http_content_type = "application/json"; break;
                case COAP_MEDIATYPE_APPLICATION_CBOR:           http_content_type = "application/cbor"; break;
                default:                                        http_content_type = "unknown"; break;
            }
            MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, http_content_type);

            // HTTP Code
            unsigned int http_code;
            switch(received->hdr->code) {
                case COAP_RESPONSE_200:         http_code = MHD_HTTP_NO_CONTENT;            break; /* 2.00 OK */
                case COAP_RESPONSE_201:         http_code = MHD_HTTP_CREATED;               break; /* 2.01 Created */
                case COAP_RESPONSE_CODE(205):   http_code = MHD_HTTP_OK;                    break;
                case COAP_RESPONSE_304:         http_code = MHD_HTTP_ACCEPTED;              break; /* 2.03 Valid */
                case COAP_RESPONSE_400:         http_code = MHD_HTTP_BAD_REQUEST;           break; /* 4.00 Bad Request */
                case COAP_RESPONSE_404:         http_code = MHD_HTTP_NOT_FOUND;             break; /* 4.04 Not Found */
                case COAP_RESPONSE_405:         http_code = MHD_HTTP_NOT_ACCEPTABLE;        break; /* 4.05 Method Not Allowed */
                case COAP_RESPONSE_415:         http_code = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE;break; /* 4.15 Unsupported Media Type */
                case COAP_RESPONSE_500:         http_code = MHD_HTTP_INTERNAL_SERVER_ERROR; break; /* 5.00 Internal Server Error */
                case COAP_RESPONSE_501:         http_code = MHD_HTTP_NOT_IMPLEMENTED;       break; /* 5.01 Not Implemented */
                case COAP_RESPONSE_503:         http_code = MHD_HTTP_SERVICE_UNAVAILABLE;   break; /* 5.03 Service Unavailable */
                case COAP_RESPONSE_504:         http_code = MHD_HTTP_GATEWAY_TIMEOUT;       break; /* 5.04 Gateway Timeout */
                default:                        http_code = MHD_HTTP_INTERNAL_SERVER_ERROR; break;
            }

            // Send the response
            MHD_queue_response(connection, http_code, response);
            MHD_destroy_response(response);

            const struct sockaddr_in *client_addr = (const struct sockaddr_in *)
                    MHD_get_connection_info(connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS)->client_addr;
            printf("HTTP %13s:%-5u <- %u %s [ %s, %zu bytes, \"%s\" ]\n", inet_ntoa(client_addr->sin_addr),
                   ntohs(client_addr->sin_port), http_code, http_reason_phrase_for(http_code),
                   http_content_type, len, (databuf != NULL) ? (char *)databuf : "");
        }

        // clear the association
        http_coap_pairs[i].connection = NULL;
        return;
    }
}
Exemplo n.º 3
0
int
coap_read(coap_context_t *ctx,
	  struct sockaddr_in6 *src, void *buf,
	  uint16_t bytes_read, struct ip6_metadata *meta) {
  coap_queue_t *node;
  coap_opt_t *opt;

  if ( bytes_read < 0 ) {
    return -1;
  }

  if ( bytes_read < sizeof(coap_hdr_t) || ((coap_hdr_t *)buf)->version != COAP_DEFAULT_VERSION ) {
#ifndef NDEBUG
    //fprintf(stderr, "coap_read: discarded invalid frame\n" );
#endif
    return -1;
  }
  node = coap_new_node();
  if ( !node )
    return -1;

  node->pdu = coap_new_pdu();
  if ( !node->pdu ) {
    coap_delete_node( node );
    return -1;
  }

  /*printf("** coap: coap_read pointers %p %p, %p %p\n",
    &node->remote,
    node->remote,
    src,
    *src,
    sizeof(src),
    sizeof(*src));*/

  memcpy( &node->remote, src, sizeof( *src ) );

  /* "parse" received PDU by filling pdu structure */
  memcpy( node->pdu->hdr, buf, bytes_read );
  node->pdu->length = bytes_read;

  /* finally calculate beginning of data block */
  options_end( node->pdu, &opt );

  if ( (unsigned char *)node->pdu->hdr + node->pdu->length <
       (unsigned char *)opt )
    node->pdu->data = (unsigned char *)node->pdu->hdr + node->pdu->length;
  else
    node->pdu->data = (unsigned char *)opt;

  /* and add new node to receive queue */
  coap_insert_node( &ctx->recvqueue, node, order_transaction_id );

#ifndef NDEBUG
  if ( inet_ntop(src.sin6_family, &src.sin6_addr, addr, INET6_ADDRSTRLEN) == 0 ) {
    //perror("coap_read: inet_ntop");
  } else {
    printf( "** received from [%s]:%d:\n  ",addr,ntohs(src.sin6_port));
  }
  coap_show_pdu( node->pdu );
#endif

  return 0;
}
Exemplo n.º 4
0
//This function is called back by libcoap when a request is received
static void HandleCoAPRequests(struct coap_context_t *ctx,
        const coap_queue_t * rcvdRequest)
{
    // silence warnings
    (void) ctx;
    OCServerProtocolRequest protocolRequest = {(OCMethod)0};
    coap_block_t rcvdBlock1;
    coap_block_t rcvdBlock2;
    memset(&rcvdBlock1, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t));
    memset(&rcvdBlock2, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t));
    uint16_t rcvdSize1 = 0;
    coap_pdu_t * rcvdPdu = rcvdRequest->pdu;
    coap_pdu_t * sendPdu = NULL;
    coap_send_flags_t sendFlag;
    OCStackResult result = OC_STACK_ERROR;
    OCStackResult requestResult = OC_STACK_ERROR;

    if(myStackMode == OC_CLIENT)
    {
        //TODO: should the client be responding to requests?
        return;
    }

    protocolRequest.observationOption = OC_OBSERVE_NO_OPTION;
    protocolRequest.qos = (rcvdPdu->hdr->type == COAP_MESSAGE_CON) ?
            OC_HIGH_QOS : OC_LOW_QOS;
    protocolRequest.coapID = rcvdPdu->hdr->id;
    protocolRequest.delayedResNeeded = rcvdRequest->delayedResNeeded;
    protocolRequest.secured = rcvdRequest->secure;

    // fill OCCoAPToken structure
    RetrieveOCCoAPToken(rcvdPdu, &protocolRequest.requestToken);
    OC_LOG_V(INFO, TAG, " Token received %d bytes",
            protocolRequest.requestToken.tokenLength);
    OC_LOG_BUFFER(INFO, TAG, protocolRequest.requestToken.token,
            protocolRequest.requestToken.tokenLength);

    // fill OCDevAddr
    memcpy(&protocolRequest.requesterAddr, (OCDevAddr *) &rcvdRequest->remote,
            sizeof(OCDevAddr));

    // Retrieve Uri and Query from received coap pdu
    result =  ParseCoAPPdu(rcvdPdu, protocolRequest.resourceUrl,
            protocolRequest.query,
            &(protocolRequest.observationOption), NULL,
            &(protocolRequest.numRcvdVendorSpecificHeaderOptions),
            protocolRequest.rcvdVendorSpecificHeaderOptions,
            &rcvdBlock1, &rcvdBlock2, &rcvdSize1, NULL,
            protocolRequest.reqJSONPayload);
    VERIFY_SUCCESS(result, OC_STACK_OK);

    switch (rcvdPdu->hdr->code)
    {
        case COAP_REQUEST_GET:
        {
            protocolRequest.method = OC_REST_GET;
            break;
        }
        case COAP_REQUEST_POST:
        {
            protocolRequest.method = OC_REST_POST;
            break;
        }
        case COAP_REQUEST_DELETE:
        {
            protocolRequest.method = OC_REST_DELETE;
            break;
        }
        case COAP_REQUEST_PUT:
        {
            protocolRequest.method = OC_REST_PUT;
            break;
        }
        default:
        {
            OC_LOG_V(ERROR, TAG, "Received CoAP method %d not supported",
                    rcvdPdu->hdr->code);
            goto exit;
        }
    }

    if(rcvdBlock1.szx != 7)
    {
        protocolRequest.reqPacketSize = 1 << (rcvdBlock1.szx + 4);
        protocolRequest.reqMorePacket = rcvdBlock1.m;
        protocolRequest.reqPacketNum  = rcvdBlock1.num;
    }
    else
    {
        // No block1 received
        rcvdSize1 = strlen((const char *)protocolRequest.reqJSONPayload)+1;
        protocolRequest.reqTotalSize = rcvdSize1;
    }

    if(rcvdBlock2.szx != 7)
    {
        protocolRequest.resPacketSize = 1 << (rcvdBlock2.szx + 4);
        protocolRequest.resPacketNum  = rcvdBlock2.num;
    }

    requestResult = HandleStackRequests(&protocolRequest);

    if(requestResult == OC_STACK_VIRTUAL_DO_NOT_HANDLE ||
            requestResult == OC_STACK_OK ||
            requestResult == OC_STACK_RESOURCE_CREATED ||
            requestResult == OC_STACK_RESOURCE_DELETED ||
            requestResult == OC_STACK_INVALID_DEVICE_INFO)
    {
        goto exit;
    }
    else if(requestResult == OC_STACK_NO_MEMORY ||
            requestResult == OC_STACK_ERROR ||
            requestResult == OC_STACK_NOTIMPL ||
            requestResult == OC_STACK_NO_RESOURCE ||
            requestResult == OC_STACK_RESOURCE_ERROR)
    {
        // TODO: should we send an error also when we receive a non-secured request to a secure resource?
        // TODO: should we consider some sort of error response
        OC_LOG(DEBUG, TAG, PCF("We should send some sort of error message"));
        // generate the pdu, if the request was CON, then the response is ACK, otherwire NON
        sendPdu = GenerateCoAPPdu((rcvdPdu->hdr->type == COAP_MESSAGE_CON)? COAP_MESSAGE_ACK : COAP_MESSAGE_NON,
                OCToCoAPResponseCode(requestResult), rcvdPdu->hdr->id,
                &protocolRequest.requestToken, NULL, NULL);
        VERIFY_NON_NULL(sendPdu);
        coap_show_pdu(sendPdu);
        sendFlag = (coap_send_flags_t)(rcvdRequest->secure ? SEND_SECURE_PORT : 0);
        if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
                sendFlag)
                != OC_STACK_OK){
            OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
        }
        goto exit;
    }
    else if(requestResult == OC_STACK_SLOW_RESOURCE)
    {
        if(rcvdPdu->hdr->type == COAP_MESSAGE_CON)
        {
            // generate the pdu, if the request was CON, then the response is ACK, otherwire NON
            sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0, rcvdPdu->hdr->id,
                    NULL, NULL, NULL);
            VERIFY_NON_NULL(sendPdu);
            coap_show_pdu(sendPdu);

            sendFlag = (coap_send_flags_t)(rcvdRequest->secure ? SEND_SECURE_PORT : 0);
            if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
                    sendFlag)
                    != OC_STACK_OK){
                OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
            }
        }
        else
        {
            goto exit;
        }
    }
exit:
    return;
}
Exemplo n.º 5
0
/*  to do 
 * Function:    _wilddog_coap_receive.
 * Description: recv coap packet and handle it.
 *   
 * Input:       N/A.
 * Output:      N/A.
 * Return:      Wilddog_Return_T type
*/
Wilddog_Return_T WD_SYSTEM _wilddog_coap_receive(void *p_arg,int flag)
{
    int res =0;
    u32 recv_type = 0;
    u32 ack_type = COAP_MESSAGE_ACK;
    u32 tmp_tokenLen = 0;
    u32 tmp_token = 0;
    u32 tmp_mid = 0;
    Protocol_recvArg_T recvArg;
    coap_pdu_t *p_pdu = NULL;

    memset(&recvArg,0,sizeof(Protocol_recvArg_T));

    recvArg.p_recvData = _wilddog_coap_mallocRecvBuffer();
    if( recvArg.p_recvData  == NULL)
    {
        wilddog_debug_level(WD_DEBUG_ERROR, "malloc failed!");
        return WILDDOG_ERR_NULL;
    }
    
    res = _wilddog_sec_recv((void*)recvArg.p_recvData,(s32)WILDDOG_PROTO_MAXSIZE);
    /*@ NO enougth space */
    if( res <= 0 || res  > WILDDOG_PROTO_MAXSIZE ) 
        goto _COAPRECV_ERR;

    recvArg.d_recvDataLen = res;

    /* distinguish recv an coap packet. */
    p_pdu = _wilddog_recvCoap(recvArg.p_recvData,recvArg.d_recvDataLen);
    if(p_pdu == NULL)
        goto _COAPRECV_ERR; 
    
#ifdef WILDDOG_SELFTEST                        
    ramtest_caculate_peakRam();             
    performtest_getHandleRecvDtlsTime();
#endif  

#ifdef WILDDOG_DEBUG
#if DEBUG_LEVEL <= WD_DEBUG_LOG
    printf("recv:\n");
    coap_show_pdu(p_pdu);
#endif
#endif
    /* dispatch .*/
    recvArg.d_recvDataLen = WILDDOG_PROTO_MAXSIZE;
    if( _wilddog_recv_dispatch(p_pdu,&recvArg) < 0)
    {
        coap_delete_pdu(p_pdu);
        goto _COAPRECV_ERR;
            
    }
    tmp_mid = p_pdu->hdr->id;
    recv_type = p_pdu->hdr->type;
    tmp_tokenLen = p_pdu->hdr->token_length;
    memcpy(&tmp_token,p_pdu->hdr->token,p_pdu->hdr->token_length);

    coap_delete_pdu(p_pdu);
    /* call back.*/
    if( _wilddog_coap_findRespondNode(&recvArg) != TRUE)
        ack_type = COAP_MESSAGE_RST;
    /* ack */
    _wilddog_coap_ackSend(recv_type,ack_type,tmp_mid,tmp_tokenLen,tmp_token);
    _wilddog_coap_freeRecvBuffer( recvArg.p_recvData );
   
    return  WILDDOG_ERR_NOERR;
   
_COAPRECV_ERR:
    _wilddog_coap_freeRecvBuffer( recvArg.p_recvData );
    return WILDDOG_ERR_NULL;
}