pick up wakaama files from https://github.com/eclipse/wakaama
core/block1.c@0:1fa43ab66921, 2017-04-19 (annotated)
- Committer:
- terencez
- Date:
- Wed Apr 19 11:30:02 2017 +0000
- Revision:
- 0:1fa43ab66921
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
terencez | 0:1fa43ab66921 | 1 | /******************************************************************************* |
terencez | 0:1fa43ab66921 | 2 | * |
terencez | 0:1fa43ab66921 | 3 | * Copyright (c) 2016 Intel Corporation and others. |
terencez | 0:1fa43ab66921 | 4 | * All rights reserved. This program and the accompanying materials |
terencez | 0:1fa43ab66921 | 5 | * are made available under the terms of the Eclipse Public License v1.0 |
terencez | 0:1fa43ab66921 | 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. |
terencez | 0:1fa43ab66921 | 7 | * |
terencez | 0:1fa43ab66921 | 8 | * The Eclipse Public License is available at |
terencez | 0:1fa43ab66921 | 9 | * http://www.eclipse.org/legal/epl-v10.html |
terencez | 0:1fa43ab66921 | 10 | * The Eclipse Distribution License is available at |
terencez | 0:1fa43ab66921 | 11 | * http://www.eclipse.org/org/documents/edl-v10.php. |
terencez | 0:1fa43ab66921 | 12 | * |
terencez | 0:1fa43ab66921 | 13 | * Contributors: |
terencez | 0:1fa43ab66921 | 14 | * Simon Bernard - initial API and implementation |
terencez | 0:1fa43ab66921 | 15 | * |
terencez | 0:1fa43ab66921 | 16 | *******************************************************************************/ |
terencez | 0:1fa43ab66921 | 17 | /* |
terencez | 0:1fa43ab66921 | 18 | Copyright (c) 2016 Intel Corporation |
terencez | 0:1fa43ab66921 | 19 | |
terencez | 0:1fa43ab66921 | 20 | Redistribution and use in source and binary forms, with or without modification, |
terencez | 0:1fa43ab66921 | 21 | are permitted provided that the following conditions are met: |
terencez | 0:1fa43ab66921 | 22 | |
terencez | 0:1fa43ab66921 | 23 | * Redistributions of source code must retain the above copyright notice, |
terencez | 0:1fa43ab66921 | 24 | this list of conditions and the following disclaimer. |
terencez | 0:1fa43ab66921 | 25 | * Redistributions in binary form must reproduce the above copyright notice, |
terencez | 0:1fa43ab66921 | 26 | this list of conditions and the following disclaimer in the documentation |
terencez | 0:1fa43ab66921 | 27 | and/or other materials provided with the distribution. |
terencez | 0:1fa43ab66921 | 28 | * Neither the name of Intel Corporation nor the names of its contributors |
terencez | 0:1fa43ab66921 | 29 | may be used to endorse or promote products derived from this software |
terencez | 0:1fa43ab66921 | 30 | without specific prior written permission. |
terencez | 0:1fa43ab66921 | 31 | |
terencez | 0:1fa43ab66921 | 32 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
terencez | 0:1fa43ab66921 | 33 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
terencez | 0:1fa43ab66921 | 34 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
terencez | 0:1fa43ab66921 | 35 | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
terencez | 0:1fa43ab66921 | 36 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
terencez | 0:1fa43ab66921 | 37 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
terencez | 0:1fa43ab66921 | 38 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
terencez | 0:1fa43ab66921 | 39 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
terencez | 0:1fa43ab66921 | 40 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
terencez | 0:1fa43ab66921 | 41 | THE POSSIBILITY OF SUCH DAMAGE. |
terencez | 0:1fa43ab66921 | 42 | */ |
terencez | 0:1fa43ab66921 | 43 | #include "internals.h" |
terencez | 0:1fa43ab66921 | 44 | |
terencez | 0:1fa43ab66921 | 45 | #include <stdlib.h> |
terencez | 0:1fa43ab66921 | 46 | #include <string.h> |
terencez | 0:1fa43ab66921 | 47 | #include <stdio.h> |
terencez | 0:1fa43ab66921 | 48 | |
terencez | 0:1fa43ab66921 | 49 | // the maximum payload transferred by block1 we accumulate per server |
terencez | 0:1fa43ab66921 | 50 | #define MAX_BLOCK1_SIZE 4096 |
terencez | 0:1fa43ab66921 | 51 | |
terencez | 0:1fa43ab66921 | 52 | coap_status_t coap_block1_handler(lwm2m_block1_data_t ** pBlock1Data, |
terencez | 0:1fa43ab66921 | 53 | uint16_t mid, |
terencez | 0:1fa43ab66921 | 54 | uint8_t * buffer, |
terencez | 0:1fa43ab66921 | 55 | size_t length, |
terencez | 0:1fa43ab66921 | 56 | uint16_t blockSize, |
terencez | 0:1fa43ab66921 | 57 | uint32_t blockNum, |
terencez | 0:1fa43ab66921 | 58 | bool blockMore, |
terencez | 0:1fa43ab66921 | 59 | uint8_t ** outputBuffer, |
terencez | 0:1fa43ab66921 | 60 | size_t * outputLength) |
terencez | 0:1fa43ab66921 | 61 | { |
terencez | 0:1fa43ab66921 | 62 | lwm2m_block1_data_t * block1Data = *pBlock1Data;; |
terencez | 0:1fa43ab66921 | 63 | |
terencez | 0:1fa43ab66921 | 64 | // manage new block1 transfer |
terencez | 0:1fa43ab66921 | 65 | if (blockNum == 0) |
terencez | 0:1fa43ab66921 | 66 | { |
terencez | 0:1fa43ab66921 | 67 | // we already have block1 data for this server, clear it |
terencez | 0:1fa43ab66921 | 68 | if (block1Data != NULL) |
terencez | 0:1fa43ab66921 | 69 | { |
terencez | 0:1fa43ab66921 | 70 | lwm2m_free(block1Data->block1buffer); |
terencez | 0:1fa43ab66921 | 71 | } |
terencez | 0:1fa43ab66921 | 72 | else |
terencez | 0:1fa43ab66921 | 73 | { |
terencez | 0:1fa43ab66921 | 74 | block1Data = lwm2m_malloc(sizeof(lwm2m_block1_data_t)); |
terencez | 0:1fa43ab66921 | 75 | *pBlock1Data = block1Data; |
terencez | 0:1fa43ab66921 | 76 | if (NULL == block1Data) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 77 | } |
terencez | 0:1fa43ab66921 | 78 | |
terencez | 0:1fa43ab66921 | 79 | block1Data->block1buffer = lwm2m_malloc(length); |
terencez | 0:1fa43ab66921 | 80 | block1Data->block1bufferSize = length; |
terencez | 0:1fa43ab66921 | 81 | |
terencez | 0:1fa43ab66921 | 82 | // write new block in buffer |
terencez | 0:1fa43ab66921 | 83 | memcpy(block1Data->block1buffer, buffer, length); |
terencez | 0:1fa43ab66921 | 84 | block1Data->lastmid = mid; |
terencez | 0:1fa43ab66921 | 85 | } |
terencez | 0:1fa43ab66921 | 86 | // manage already started block1 transfer |
terencez | 0:1fa43ab66921 | 87 | else |
terencez | 0:1fa43ab66921 | 88 | { |
terencez | 0:1fa43ab66921 | 89 | if (block1Data == NULL) |
terencez | 0:1fa43ab66921 | 90 | { |
terencez | 0:1fa43ab66921 | 91 | // we never receive the first block |
terencez | 0:1fa43ab66921 | 92 | // TODO should we clean block1 data for this server ? |
terencez | 0:1fa43ab66921 | 93 | return COAP_408_REQ_ENTITY_INCOMPLETE; |
terencez | 0:1fa43ab66921 | 94 | } |
terencez | 0:1fa43ab66921 | 95 | |
terencez | 0:1fa43ab66921 | 96 | // If this is a retransmission, we already did that. |
terencez | 0:1fa43ab66921 | 97 | if (block1Data->lastmid != mid) |
terencez | 0:1fa43ab66921 | 98 | { |
terencez | 0:1fa43ab66921 | 99 | uint8_t * oldBuffer = block1Data->block1buffer; |
terencez | 0:1fa43ab66921 | 100 | size_t oldSize = block1Data->block1bufferSize; |
terencez | 0:1fa43ab66921 | 101 | |
terencez | 0:1fa43ab66921 | 102 | if (block1Data->block1bufferSize != blockSize * blockNum) |
terencez | 0:1fa43ab66921 | 103 | { |
terencez | 0:1fa43ab66921 | 104 | // we don't receive block in right order |
terencez | 0:1fa43ab66921 | 105 | // TODO should we clean block1 data for this server ? |
terencez | 0:1fa43ab66921 | 106 | return COAP_408_REQ_ENTITY_INCOMPLETE; |
terencez | 0:1fa43ab66921 | 107 | } |
terencez | 0:1fa43ab66921 | 108 | |
terencez | 0:1fa43ab66921 | 109 | // is it too large? |
terencez | 0:1fa43ab66921 | 110 | if (block1Data->block1bufferSize + length >= MAX_BLOCK1_SIZE) { |
terencez | 0:1fa43ab66921 | 111 | return COAP_413_ENTITY_TOO_LARGE; |
terencez | 0:1fa43ab66921 | 112 | } |
terencez | 0:1fa43ab66921 | 113 | // re-alloc new buffer |
terencez | 0:1fa43ab66921 | 114 | block1Data->block1bufferSize = oldSize+length; |
terencez | 0:1fa43ab66921 | 115 | block1Data->block1buffer = lwm2m_malloc(block1Data->block1bufferSize); |
terencez | 0:1fa43ab66921 | 116 | if (NULL == block1Data->block1buffer) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 117 | memcpy(block1Data->block1buffer, oldBuffer, oldSize); |
terencez | 0:1fa43ab66921 | 118 | lwm2m_free(oldBuffer); |
terencez | 0:1fa43ab66921 | 119 | |
terencez | 0:1fa43ab66921 | 120 | // write new block in buffer |
terencez | 0:1fa43ab66921 | 121 | memcpy(block1Data->block1buffer + oldSize, buffer, length); |
terencez | 0:1fa43ab66921 | 122 | block1Data->lastmid = mid; |
terencez | 0:1fa43ab66921 | 123 | } |
terencez | 0:1fa43ab66921 | 124 | } |
terencez | 0:1fa43ab66921 | 125 | |
terencez | 0:1fa43ab66921 | 126 | if (blockMore) |
terencez | 0:1fa43ab66921 | 127 | { |
terencez | 0:1fa43ab66921 | 128 | *outputLength = -1; |
terencez | 0:1fa43ab66921 | 129 | return COAP_231_CONTINUE; |
terencez | 0:1fa43ab66921 | 130 | } |
terencez | 0:1fa43ab66921 | 131 | else |
terencez | 0:1fa43ab66921 | 132 | { |
terencez | 0:1fa43ab66921 | 133 | // buffer is full, set output parameter |
terencez | 0:1fa43ab66921 | 134 | // we don't free it to be able to send retransmission |
terencez | 0:1fa43ab66921 | 135 | *outputLength = block1Data->block1bufferSize; |
terencez | 0:1fa43ab66921 | 136 | *outputBuffer = block1Data->block1buffer; |
terencez | 0:1fa43ab66921 | 137 | |
terencez | 0:1fa43ab66921 | 138 | return NO_ERROR; |
terencez | 0:1fa43ab66921 | 139 | } |
terencez | 0:1fa43ab66921 | 140 | } |
terencez | 0:1fa43ab66921 | 141 | |
terencez | 0:1fa43ab66921 | 142 | void free_block1_buffer(lwm2m_block1_data_t * block1Data) |
terencez | 0:1fa43ab66921 | 143 | { |
terencez | 0:1fa43ab66921 | 144 | if (block1Data != NULL) |
terencez | 0:1fa43ab66921 | 145 | { |
terencez | 0:1fa43ab66921 | 146 | // free block1 buffer |
terencez | 0:1fa43ab66921 | 147 | lwm2m_free(block1Data->block1buffer); |
terencez | 0:1fa43ab66921 | 148 | block1Data->block1bufferSize = 0 ; |
terencez | 0:1fa43ab66921 | 149 | |
terencez | 0:1fa43ab66921 | 150 | // free current element |
terencez | 0:1fa43ab66921 | 151 | lwm2m_free(block1Data); |
terencez | 0:1fa43ab66921 | 152 | } |
terencez | 0:1fa43ab66921 | 153 | } |