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