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