All files / node-coap/lib segmentation.js

94.55% Statements 52/55
71.43% Branches 10/14
100% Functions 8/8
94.55% Lines 52/55

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                    1x 1x 1x     9x 2x     7x           7x   7x 7x 7x   7x 7x 7x   7x 7x     1x 8x 8x     1x 1x 1x   1x     1x 2x     1x 2x 1x 1x     1x   1x                   1x 1x       1x 1x   1x     1x 3x     1x 1x 1x 1x   1x 1x 1x   1x   1x 1x     1x 1x   1x 1x             1x  
'use strict'
 
/*
 * Copyright (c) 2013-2021 node-coap contributors.
 *
 * node-coap is licensed under an MIT +no-false-attribs license.
 * All rights not explicitly granted in the MIT license are reserved.
 * See the included LICENSE file for more details.
 */
 
var generate           = require('coap-packet').generate
 , generateBlockOption = require('./block').generateBlockOption
 , exponentToByteSize  = require('./block').exponentToByteSize
 
function SegmentedTransmission(blockSize, req, packet) {
  if(blockSize < 0 || blockSize > 6) {
    throw new Error("invalid block size " + blockSize)
  }
 
  this.blockState = {
    sequenceNumber: 0,
    moreBlocks: false,
    blockSize: 0
  }
 
  this.setBlockSizeExp(blockSize)
 
  this.totalLength = packet.payload.length
  this.currentByte = 0
  this.lastByte = 0
 
  this.req = req
  this.payload = packet.payload
  this.packet = packet
 
  this.packet.payload = null
  this.resendCount = 0
}
 
SegmentedTransmission.prototype.setBlockSizeExp = function setBlockSizeExp(blockSizeExp) {
  this.blockState.blockSize = blockSizeExp
  this.byteSize = exponentToByteSize(blockSizeExp)
}
 
SegmentedTransmission.prototype.updateBlockState = function updateBlockState() {
  this.blockState.sequenceNumber = this.currentByte / this.byteSize
  this.blockState.moreBlocks = ((this.currentByte + this.byteSize) < this.totalLength)?1:0
 
  this.req.setOption("Block1", generateBlockOption(this.blockState))
}
 
SegmentedTransmission.prototype.isCorrectACK = function isCorrectACK(packet, retBlockState) {
  return retBlockState.sequenceNumber == this.blockState.sequenceNumber// && packet.code == "2.31"
}
 
SegmentedTransmission.prototype.resendPreviousPacket = function resendPreviousPacket() {
  if(this.resendCount < 5) {
    this.currentByte = this.lastByte
    Iif(this.remaining() > 0) {
      this.sendNext()
    }
    this.resendCount++
  } else {
    throw new Error("Too many block re-transfers")
  }
}
 
/**
 * 
 * @param {Packet} packet The packet received which contained the ack
 * @param {Object} retBlockState The received block state from the other end 
 * @returns {Boolean} Returns true if the ACK was for the correct block. 
 */
SegmentedTransmission.prototype.receiveACK = function receiveACK(packet, retBlockState) {
  Iif(this.blockState.blockSize !== retBlockState.blockSize) {
    this.setBlockSizeExp(retBlockState.blockSize)
  }
 
  Eif(this.remaining() > 0) {
    this.sendNext()
  }
  this.resendCount = 0
}
 
SegmentedTransmission.prototype.remaining = function remaining() {
  return this.totalLength - this.currentByte
}
 
SegmentedTransmission.prototype.sendNext = function sendNext() {
  var blockLength = Math.min(this.totalLength - this.currentByte, this.byteSize)
  var subBuffer = this.payload.slice(this.currentByte, this.currentByte + blockLength)
  this.updateBlockState()
 
  this.packet.ack = false
  this.packet.reset = false
  this.packet.confirmable = true
 
  this.packet.payload = subBuffer
 
  this.lastByte = this.currentByte
  this.currentByte += blockLength
  var buf
  
  try {
    buf = generate(this.packet)
  } catch(err) {
    this.req.sender.reset()
    return this.req.emit('error', err)
  }
  this.req.sender.send(buf, !this.packet.confirmable)
}
 
 
 
module.exports.SegmentedTransmission = SegmentedTransmission