예제 #1
0
boolean Protocol::parseByte(uint8_t data) {
  switch(m_mode) {
  case MODE_HEADER0:
  case MODE_PAYLOAD_READY: // If we get new data before a payload is handled, just start over.
    if(data == HEADER0) {
      reset();
      m_mode = MODE_HEADER1;
      updateCRC(data);
    }
    else {
    }
    break;
  case MODE_HEADER1:
    if(data == HEADER1) {
      m_mode = MODE_LENGTH;
      updateCRC(data);
    }
    else {
      reset();
    }
    break;
  case MODE_LENGTH:
    if(data <= MAX_DATA_SIZE && data > 0) {
      m_mode = MODE_PAYLOAD;
      m_expectedLength = data;
      updateCRC(data);
    }
    else {
      reset();
    }
    break;
  case MODE_PAYLOAD:
    addByte(data);
    if(m_packetLength >= m_expectedLength) {  // TODO: why >= and not just ==?
      m_mode = MODE_CRC;
    } 
    break;
  case MODE_CRC:
    if(data == m_crc) {
      m_mode = MODE_PAYLOAD_READY;
    }
    else {
      reset();
    }
    break;
  default:
    reset();
  }

  return (m_mode == MODE_PAYLOAD_READY);
}
예제 #2
0
/**
 * Transmit a NACK through the telemetry link.
 * \param[in] objId the ObjectID we rejected
 */
bool UAVTalk::transmitNack(quint32 objId)
{
    int dataOffset = 8;

    txBuffer[0] = SYNC_VAL;
    txBuffer[1] = TYPE_NACK;
    qToLittleEndian<quint32>(objId, &txBuffer[4]);

    // Calculate checksum
    txBuffer[dataOffset] = updateCRC(0, txBuffer, dataOffset);

    qToLittleEndian<quint16>(dataOffset, &txBuffer[2]);


    // Send buffer, check that the transmit backlog does not grow above limit
    if ( io->bytesToWrite() < TX_BUFFER_SIZE )
    {
        io->write((const char*)txBuffer, dataOffset+CHECKSUM_LENGTH);
    }
    else
    {
        ++stats.txErrors;
        return false;
    }

    // Update stats
    stats.txBytes += 8+CHECKSUM_LENGTH;

    // Done
    return true;

}
예제 #3
0
파일: uavtalk.cpp 프로젝트: Crash1/TauLabs
/**
 * Transmit a NACK through the telemetry link.
 * This method is separate from transmitsingleobject because we are
 * using an objectID for an unknown object.
 * \param[in] objId the ObjectID we rejected
 */
bool UAVTalk::transmitNack(quint32 objId)
{
    int dataOffset = 8;

    txBuffer[0] = SYNC_VAL;
    txBuffer[1] = TYPE_NACK;
    qToLittleEndian<quint32>(objId, &txBuffer[4]);

    // Calculate checksum
    txBuffer[dataOffset] = updateCRC(0, txBuffer, dataOffset);

    qToLittleEndian<quint16>(dataOffset, &txBuffer[2]);

    // Send buffer, check that the transmit backlog does not grow above limit
    if (io && io->isWritable() && io->bytesToWrite() < TX_BUFFER_SIZE )
    {
        io->write((const char*)txBuffer, dataOffset+CHECKSUM_LENGTH);
        if(useUDPMirror)
        {
            udpSocketRx->writeDatagram((const char*)txBuffer,dataOffset+CHECKSUM_LENGTH,QHostAddress::LocalHost,udpSocketTx->localPort());
        }
    }
    else
    {
        ++stats.txErrors;
        return false;
    }

    // Update stats
    stats.txBytes += 8+CHECKSUM_LENGTH;

    // Done
    return true;

}
예제 #4
0
파일: decompress.c 프로젝트: enadam/bzip
void bs_put_byte(u_int8_t c)
{
	assert(INRANGE(output_bs.byte_p,
		output_bs.byte_window, output_bs.byte_end));

	if (output_bs.byte_p == output_bs.byte_end)
		bs_flush_byte(&output_bs);
	updateCRC(output_bs.crc, c);
	*output_bs.byte_p++ = c;
} /* bs_put_byte */
예제 #5
0
bool DS18B20::duty(OneWireHub *hub)
{
    const uint8_t cmd = hub->recv();
    //if (hub->getError())  return false;

    switch (cmd)
    {
        case 0x44: // CONVERT T --> start a new measurement conversion
            //hub->sendBit(1); // 1 is passive ...
            break;

        case 0x4E: // WRITE SCRATCHPAD
            // write 3 byte of data to scratchpad[1:3]
            hub->recv(&scratchpad[2], 3);
            updateCRC();
            break;

        case 0xBE: // READ SCRATCHPAD
            hub->send(scratchpad, 9);
            if (hub->getError()) return false;
            break;

        case 0x48: // COPY SCRATCHPAD to EEPROM
            // send1 if parasite power is used
            break;

        case 0xB8: // RECALL E2 (EEPROM to 3byte from Scratchpad)
            //hub->sendBit(1); // signal that OP is done // 1 is passive ...
            break;

        case 0xB4: // READ POWER SUPPLY
            //hub->sendBit(1); // 1: say i am external powered, 0: uses parasite power, // 1 is passive, so ommit it ...
            break;

            // READ TIME SLOTS, respond with 1 if conversion is done, not usable with parasite power

            //  write trim2               0x63
            //  copy trim2                0x64
            //  read trim2                0x68
            //  read trim1                0x93
            //  copy trim1                0x94
            //  write trim1               0x95
        case 0xEC:
            // TODO: Alarm search command, respond if flag is set
            break;


        default:
            hub->raiseSlaveError(cmd);
            break;
    };

    return true;
};
예제 #6
0
//=================== DS18S20 ==========================================
DS18B20::DS18B20(byte ID1, byte ID2, byte ID3, byte ID4, byte ID5, byte ID6, byte ID7): OneWireItem(ID1, ID2, ID3, ID4, ID5, ID6, ID7){
  this->scratchpad[0] = 0xB4; // TLSB
  this->scratchpad[1] = 0x09; // TMSB
  this->scratchpad[2] = 0x4B; // THRE
  this->scratchpad[3] = 0x46; // TLRE
  this->scratchpad[4] = 0x1F; // Conf
  this->scratchpad[5] = 0xFF; // 0xFF
  this->scratchpad[6] = 0x00; // Rese
  this->scratchpad[7] = 0x10; // 0x10
  this->scratchpad[8] = 0x00; // CRC
  updateCRC();
}
예제 #7
0
DS18B20::DS18B20(uint8_t ID1, uint8_t ID2, uint8_t ID3, uint8_t ID4, uint8_t ID5, uint8_t ID6, uint8_t ID7) : OneWireItem(ID1, ID2, ID3, ID4, ID5, ID6, ID7)
{
    scratchpad[0] = 0xA0; // TLSB --> 10 degC as std
    scratchpad[1] = 0x00; // TMSB
    scratchpad[2] = 0x4B; // THRE --> Trigger register TH
    scratchpad[3] = 0x46; // TLRE --> TLow
    scratchpad[4] = 0x7F; // Conf
    // = 0 R1 R0 1 1 1 1 1 --> R=0 9bit, R=3 12bit
    scratchpad[5] = 0xFF; // 0xFF
    scratchpad[6] = 0x00; // Reset
    scratchpad[7] = 0x10; // 0x10
    updateCRC(); // update scratchpad[8]
}
예제 #8
0
void DS18B20::settemp(float temp)
{  
  word ret = 0;
  bool Neg = temp < 0;
  temp = abs(temp);	
  ret = round(floor(temp)) << 4;

  if (Neg){
    ret = ret | 0x8000;
  }
 
  ret = ret | byte(16*((temp - (int)temp) * 100)/100);
  
  this->scratchpad[0] = byte(ret);
  this->scratchpad[1] = byte(ret >> 8);
  updateCRC();
}
예제 #9
0
// use always 12bit mode! also 9,10,11,12 bit possible bitPosition seems to stay the same
void DS18B20::setTempRaw(const int16_t value_raw)
{
    int16_t value = value_raw;

    if (value > 0)
    {
        value &= 0x0FFF;
    }
    else
    {
        value = -value;
        value |= 0xF000;
    };

    scratchpad[0] = uint8_t(value);
    scratchpad[1] = uint8_t(value >> 8);
    // TODO: if alarms implemented - compare TH,TL with (value>>4 & 0xFF) (bit 11to4)
    // if out of bounds >=TH, <=TL trigger flag

    updateCRC();
};
예제 #10
0
/**
 * Send an object through the telemetry link.
 * \param[in] obj Object handle to send
 * \param[in] type Transaction type
 * \return Success (true), Failure (false)
 */
bool UAVTalk::transmitSingleObject(UAVObject* obj, quint8 type, bool allInstances)
{
    qint32 length;
    qint32 dataOffset;
    quint32 objId;
    quint16 instId;
    quint16 allInstId = ALL_INSTANCES;

    // Setup type and object id fields
    objId = obj->getObjID();
    txBuffer[0] = SYNC_VAL;
    txBuffer[1] = type;
    qToLittleEndian<quint32>(objId, &txBuffer[4]);

    // Setup instance ID if one is required
    if ( obj->isSingleInstance() )
    {
        dataOffset = 8;
    }
    else
    {
        // Check if all instances are requested
        if (allInstances)
        {
            qToLittleEndian<quint16>(allInstId, &txBuffer[8]);
        }
        else
        {
            instId = obj->getInstID();
            qToLittleEndian<quint16>(instId, &txBuffer[8]);
        }
        dataOffset = 10;
    }

    // Determine data length
    if (type == TYPE_OBJ_REQ || type == TYPE_ACK)
    {
        length = 0;
    }
    else
    {
        length = obj->getNumBytes();
    }

    // Check length
    if (length >= MAX_PAYLOAD_LENGTH)
    {
        return false;
    }

    // Copy data (if any)
    if (length > 0)
    {
        if ( !obj->pack(&txBuffer[dataOffset]) )
        {
            return false;
        }
    }

    qToLittleEndian<quint16>(dataOffset + length, &txBuffer[2]);

    // Calculate checksum
    txBuffer[dataOffset+length] = updateCRC(0, txBuffer, dataOffset + length);

    // Send buffer, check that the transmit backlog does not grow above limit
    if ( io->bytesToWrite() < TX_BUFFER_SIZE )
    {
        io->write((const char*)txBuffer, dataOffset+length+CHECKSUM_LENGTH);
    }
    else
    {
        ++stats.txErrors;
        return false;
    }

    // Update stats
    ++stats.txObjects;
    stats.txBytes += dataOffset+length+CHECKSUM_LENGTH;
    stats.txObjectBytes += length;

    // Done
    return true;
}
예제 #11
0
/**
 * Process an byte from the telemetry stream.
 * \param[in] rxbyte Received byte
 * \return Success (true), Failure (false)
 */
bool UAVTalk::processInputByte(quint8 rxbyte)
{
    // Update stats
    stats.rxBytes++;

    rxPacketLength++;   // update packet byte count

    // Receive state machine
    switch (rxState)
    {
        case STATE_SYNC:

            if (rxbyte != SYNC_VAL)
            {
                UAVTALK_QXTLOG_DEBUG("UAVTalk: Sync->Sync (" + QString::number(rxbyte) + " " + QString("0x%1").arg(rxbyte,2,16) + ")");
                break;
            }

            // Initialize and update CRC
            rxCS = updateCRC(0, rxbyte);

            rxPacketLength = 1;

            rxState = STATE_TYPE;
            UAVTALK_QXTLOG_DEBUG("UAVTalk: Sync->Type");
            break;

        case STATE_TYPE:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            if ((rxbyte & TYPE_MASK) != TYPE_VER)
            {
                rxState = STATE_SYNC;
                UAVTALK_QXTLOG_DEBUG("UAVTalk: Type->Sync");
                break;
            }

            rxType = rxbyte;

            packetSize = 0;

            rxState = STATE_SIZE;
            UAVTALK_QXTLOG_DEBUG("UAVTalk: Type->Size");
            rxCount = 0;
            break;

        case STATE_SIZE:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            if (rxCount == 0)
            {
                packetSize += rxbyte;
                rxCount++;
                UAVTALK_QXTLOG_DEBUG("UAVTalk: Size->Size");
                break;
            }

            packetSize += (quint32)rxbyte << 8;

            if (packetSize < MIN_HEADER_LENGTH || packetSize > MAX_HEADER_LENGTH + MAX_PAYLOAD_LENGTH)
            {   // incorrect packet size
                rxState = STATE_SYNC;
                UAVTALK_QXTLOG_DEBUG("UAVTalk: Size->Sync");
                break;
            }

            rxCount = 0;
            rxState = STATE_OBJID;
            UAVTALK_QXTLOG_DEBUG("UAVTalk: Size->ObjID");
            break;

        case STATE_OBJID:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            rxTmpBuffer[rxCount++] = rxbyte;
            if (rxCount < 4)
            {
                UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->ObjID");
                break;
            }

            // Search for object, if not found reset state machine
            rxObjId = (qint32)qFromLittleEndian<quint32>(rxTmpBuffer);
            {
                UAVObject *rxObj = objMngr->getObject(rxObjId);
                if (rxObj == NULL && rxType != TYPE_OBJ_REQ)
                {
                    stats.rxErrors++;
                    rxState = STATE_SYNC;
                    UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Sync (badtype)");
                    break;
                }

                // Determine data length
                if (rxType == TYPE_OBJ_REQ || rxType == TYPE_ACK || rxType == TYPE_NACK)
                {
                    rxLength = 0;
                    rxInstanceLength = 0;
                }
                else
                {
                    rxLength = rxObj->getNumBytes();
                    rxInstanceLength = (rxObj->isSingleInstance() ? 0 : 2);
                }

                // Check length and determine next state
                if (rxLength >= MAX_PAYLOAD_LENGTH)
                {
                    stats.rxErrors++;
                    rxState = STATE_SYNC;
                    UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Sync (oversize)");
                    break;
                }

                // Check the lengths match
                if ((rxPacketLength + rxInstanceLength + rxLength) != packetSize)
                {   // packet error - mismatched packet size
                    stats.rxErrors++;
                    rxState = STATE_SYNC;
                    UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Sync (length mismatch)");
                    break;
                }

                // Check if this is a single instance object (i.e. if the instance ID field is coming next)
                if (rxObj == NULL)
                {
                   // This is a non-existing object, just skip to checksum
                   // and we'll send a NACK next.
                   rxState   = STATE_CS;
                   UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->CSum (no obj)");
                   rxInstId = 0;
                   rxCount = 0;
                }
                else if (rxObj->isSingleInstance())
                {
                    // If there is a payload get it, otherwise receive checksum
                    if (rxLength > 0)
                    {
                        rxState = STATE_DATA;
                        UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Data (needs data)");
                    }
                    else
                    {
                        rxState = STATE_CS;
                        UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Checksum");
                    }
                    rxInstId = 0;
                    rxCount = 0;
                }
                else
                {
                    rxState = STATE_INSTID;
                    UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->InstID");
                    rxCount = 0;
                }
            }

            break;

        case STATE_INSTID:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            rxTmpBuffer[rxCount++] = rxbyte;
            if (rxCount < 2)
            {
                UAVTALK_QXTLOG_DEBUG("UAVTalk: InstID->InstID");
                break;
            }

            rxInstId = (qint16)qFromLittleEndian<quint16>(rxTmpBuffer);

            rxCount = 0;

            // If there is a payload get it, otherwise receive checksum
            if (rxLength > 0)
            {
                rxState = STATE_DATA;
                UAVTALK_QXTLOG_DEBUG("UAVTalk: InstID->Data");
            }
            else
            {
                rxState = STATE_CS;
                UAVTALK_QXTLOG_DEBUG("UAVTalk: InstID->CSum");
            }
            break;

        case STATE_DATA:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            rxBuffer[rxCount++] = rxbyte;
            if (rxCount < rxLength)
            {
                UAVTALK_QXTLOG_DEBUG("UAVTalk: Data->Data");
                break;
            }

            rxState = STATE_CS;
            UAVTALK_QXTLOG_DEBUG("UAVTalk: Data->CSum");
            rxCount = 0;
            break;

        case STATE_CS:

            // The CRC byte
            rxCSPacket = rxbyte;

            if (rxCS != rxCSPacket)
            {   // packet error - faulty CRC
                stats.rxErrors++;
                rxState = STATE_SYNC;
                UAVTALK_QXTLOG_DEBUG("UAVTalk: CSum->Sync (badcrc)");
                break;
            }

            if (rxPacketLength != packetSize + 1)
            {   // packet error - mismatched packet size
                stats.rxErrors++;
                rxState = STATE_SYNC;
                UAVTALK_QXTLOG_DEBUG("UAVTalk: CSum->Sync (length mismatch)");
                break;
            }

            mutex->lock();
                receiveObject(rxType, rxObjId, rxInstId, rxBuffer, rxLength);
                stats.rxObjectBytes += rxLength;
                stats.rxObjects++;
            mutex->unlock();

            rxState = STATE_SYNC;
            UAVTALK_QXTLOG_DEBUG("UAVTalk: CSum->Sync (OK)");
            break;

        default:
            rxState = STATE_SYNC;
            stats.rxErrors++;
            UAVTALK_QXTLOG_DEBUG("UAVTalk: ???->Sync");
    }

    // Done
    return true;
}
예제 #12
0
/**
 * Process an byte from the telemetry stream.
 * \param[in] rxbyte Received byte
 * \return Success (true), Failure (false)
 */
bool UAVTalk::processInputByte(quint8 rxbyte)
{
	if (!objMngr || !io)	// Pip
		return false;

    // Update stats
    stats.rxBytes++;

    rxPacketLength++;   // update packet byte count

    // Receive state machine
    switch (rxState)
    {
        case STATE_SYNC:

            if (rxbyte != SYNC_VAL)
                break;

            // Initialize and update CRC
            rxCS = updateCRC(0, rxbyte);

            rxPacketLength = 1;

            rxState = STATE_TYPE;
            break;

        case STATE_TYPE:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            if ((rxbyte & TYPE_MASK) != TYPE_VER)
            {
                rxState = STATE_SYNC;
                break;
            }

            rxType = rxbyte;

            packetSize = 0;

            rxState = STATE_SIZE;
            rxCount = 0;
            break;

        case STATE_SIZE:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            if (rxCount == 0)
            {
                packetSize += rxbyte;
                rxCount++;
                break;
            }

            packetSize += (quint32)rxbyte << 8;

            if (packetSize < MIN_HEADER_LENGTH || packetSize > MAX_HEADER_LENGTH + MAX_PAYLOAD_LENGTH)
            {   // incorrect packet size
                rxState = STATE_SYNC;
                break;
            }

            rxCount = 0;
            rxState = STATE_OBJID;
            break;

        case STATE_OBJID:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            rxTmpBuffer[rxCount++] = rxbyte;
            if (rxCount < 4)
                break;

            // Search for object, if not found reset state machine
            rxObjId = (qint32)qFromLittleEndian<quint32>(rxTmpBuffer);
            {
                UAVObject *rxObj = objMngr->getObject(rxObjId);
                if (rxObj == NULL)
                {
                    stats.rxErrors++;
                    rxState = STATE_SYNC;
                    break;
                }

                // Determine data length
                if (rxType == TYPE_OBJ_REQ || rxType == TYPE_ACK)
                    rxLength = 0;
                else
                    rxLength = rxObj->getNumBytes();

                // Check length and determine next state
                if (rxLength >= MAX_PAYLOAD_LENGTH)
                {
                    stats.rxErrors++;
                    rxState = STATE_SYNC;
                    break;
                }

                // Check the lengths match
                if ((rxPacketLength + rxLength) != packetSize)
                {   // packet error - mismatched packet size
                    stats.rxErrors++;
                    rxState = STATE_SYNC;
                    break;
                }

                // Check if this is a single instance object (i.e. if the instance ID field is coming next)
                if (rxObj->isSingleInstance())
                {
                    // If there is a payload get it, otherwise receive checksum
                    if (rxLength > 0)
                        rxState = STATE_DATA;
                    else
                        rxState = STATE_CS;
                    rxInstId = 0;
                    rxCount = 0;
                }
                else
                {
                    rxState = STATE_INSTID;
                    rxCount = 0;
                }
            }

            break;

        case STATE_INSTID:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            rxTmpBuffer[rxCount++] = rxbyte;
            if (rxCount < 2)
                break;

            rxInstId = (qint16)qFromLittleEndian<quint16>(rxTmpBuffer);

            rxCount = 0;

            // If there is a payload get it, otherwise receive checksum
            if (rxLength > 0)
                rxState = STATE_DATA;
            else
                rxState = STATE_CS;

            break;

        case STATE_DATA:

            // Update CRC
            rxCS = updateCRC(rxCS, rxbyte);

            rxBuffer[rxCount++] = rxbyte;
            if (rxCount < rxLength)
                break;

            rxState = STATE_CS;
            rxCount = 0;
            break;

        case STATE_CS:

            // The CRC byte
            rxCSPacket = rxbyte;

            if (rxCS != rxCSPacket)
            {   // packet error - faulty CRC
                stats.rxErrors++;
                rxState = STATE_SYNC;
                break;
            }

            if (rxPacketLength != packetSize + 1)
            {   // packet error - mismatched packet size
                stats.rxErrors++;
                rxState = STATE_SYNC;
                break;
            }

            mutex->lock();
                receiveObject(rxType, rxObjId, rxInstId, rxBuffer, rxLength);
                stats.rxObjectBytes += rxLength;
                stats.rxObjects++;
            mutex->unlock();

            rxState = STATE_SYNC;
            break;

        default:
            rxState = STATE_SYNC;
            stats.rxErrors++;
    }

    // Done
    return true;
}
예제 #13
0
void Protocol::addByte(uint8_t data) {
  m_packetData[m_packetLength] = data;
  m_packetLength +=1;

  updateCRC(data);
}
예제 #14
0
int main(int argc, char* argv[])
{
	printf("[i] Make fimware.\n");

	if(argc < 5){
		// не задано имя файла прошивки
		printf("[!] Set file names!\n");
		help2();
		return -1;
	}

	bool isDlink = false;

	size_t size_result=0, size_bcm=0, size_cfe=0, size_sqsh=0, size_kernel=0, size_name=0;

	FILE* fresult=0, *fbcm=0, *fcfe=0, *fsqsh=0, *fkernel=0, *fname=0;

	// имя файла задаётся первым параметром
	char* file_bcm = argv[1];
	printf("[i] bcm file: %s\n", file_bcm);
	fbcm = fopen(file_bcm, "rb");
	if(fbcm){
		size_bcm = getFileSize(fbcm);
	}
	// проверим длину заголовка
	if(size_bcm!=BCM_LENGTH){
		printf("[!] Error: wrong bcm file size: %s (%d bytes)\n", file_bcm, size_bcm);
		help2();
		return -1;
	}

	char* file_cfe = argv[2];
	printf("[i] cfe file: %s\n", file_cfe);
	fcfe = fopen(file_cfe, "rb");
	if(fcfe){
		size_cfe = getFileSize(fcfe);
	}

	char* file_sqsh = argv[3];
	printf("[i] sqsh file: %s\n", file_sqsh);
	fsqsh = fopen(file_sqsh, "rb");
	if(fsqsh){
		size_sqsh = getFileSize(fsqsh);
	}
	
	char* file_kernel = argv[4];
	printf("[i] kernel file: %s\n", file_kernel);
	fkernel = fopen(file_kernel, "rb");
	if(fkernel){
		size_kernel = getFileSize(fkernel);
	}

	char* file_name = 0;
	// для прошивки от D-link-а
	if(argc>5){
		isDlink = true;
		file_name = argv[5];
		printf("[i] name file: %s\n", file_name);
		fname = fopen(file_name, "rb");
		if(fname){
			size_name = getFileSize(fname);
		}
		// проверим длину названия
		if(size_name!=NAME_LENGTH){
			printf("[!] Error: wrong name file size: %s (%d bytes)\n", file_name, size_name);
			help2();
			return -1;
		}
	}


	size_result = size_bcm + size_cfe + size_sqsh + size_kernel + size_name;

	if(!fbcm || !fcfe || !fsqsh || !fkernel){
		printf("[!] Error: cant open files!\n");
		return -2;
	}
	if(isDlink && !fname){
		printf("[!] Error: cant open name-file!\n");
		return -2;
	}

	printf("[i] result size: %d\n", size_result);

	fresult = fopen(result_file, "wb+");
	if(!fresult){
		printf("[!] Error: cant open file for writing: %s!\n", result_file);
		return -2;
	}

	//
	// буфер для сохранения
	//
	uchar* buf = new uchar [size_result];
	if(!buf){
		printf("[!] Error: cant allocate memory!\n");
		return -4;
	}

	//
	// считываем файлы в общий буфер
	//

	// bcm
	fread(buf, size_bcm, 1, fbcm);
	// cfe
	fread((uint8_t *) (buf + size_bcm), size_cfe, 1, fcfe);
	// sqsh
	fread((uint8_t *) (buf + size_bcm + size_cfe), size_sqsh, 1, fsqsh);
	// kernel
	fread((uint8_t *) (buf + size_bcm + size_cfe + size_sqsh), size_kernel, 1, fkernel);
	// name
	if(isDlink){
		fread((uint8_t *) (buf + size_bcm + size_cfe + size_sqsh + size_kernel), size_name, 1, fname);	
	}

	//
	// рассчёт CRC
	//
	uint32_t crc=CRC32_INIT_VALUE, crc_bcm=CRC32_INIT_VALUE, crc_image=CRC32_INIT_VALUE, crc_rootfs=CRC32_INIT_VALUE, crc_kernel=CRC32_INIT_VALUE;
	char file_crc[16], header_crc[16], image_crc[16], rootfs_crc[16], kernel_crc[16];

	// CRC образа cfe+sqsh+kernel
	crc_image = getCRC32String((uint8_t *) (buf + size_bcm), size_cfe+size_sqsh+size_kernel, image_crc);
	printf("[i] CRC image\t\t: 0x%s\n", image_crc);
	if(isDlink){
		// CRC образа cfe+sqsh+kernel+name
		crc_image = getCRC32String((uint8_t *) (buf + size_bcm), size_cfe+size_sqsh+size_kernel+size_name, image_crc);
		printf("[i] D-link CRC image\t\t: 0x%s\n", image_crc);
	}

	// CRC корневой файловой системы
	crc_rootfs = getCRC32String((uint8_t *) (buf + size_bcm + size_cfe), size_sqsh, rootfs_crc);
	printf("[i] CRC sqsh\t\t: 0x%s\n", rootfs_crc);

	// CRC ядра
	crc_kernel = getCRC32String((uint8_t *) (buf + size_bcm + size_cfe + size_sqsh), size_kernel, kernel_crc);
	printf("[i] CRC kernel\t\t: 0x%s\n", kernel_crc);

	//
	// запись размеров
	//
	printf("[i] update size...\n");

	// totalImageLen  = cfe+sqsh+kernel
	uint32_t place = TAG_VER_LEN+SIG_LEN+SIG_LEN_2+CHIP_ID_LEN+BOARD_ID_LEN+FLAG_LEN;
	updateLength(buf, place, size_cfe + size_sqsh + size_kernel);
	if(isDlink){
		// totalImageLen = cfe+sqsh+kernel+name
		updateLength(buf, place, size_cfe + size_sqsh + size_kernel + size_name);
	}
	// cfe
	place += IMAGE_LEN + ADDRESS_LEN;
	updateLength(buf, place, size_cfe);
	// rootFS
	place += IMAGE_LEN + ADDRESS_LEN;
	updateLength(buf, place, size_sqsh);
	// kernel
	place += IMAGE_LEN + ADDRESS_LEN;
	updateLength(buf, place, size_kernel);

	
	//
	// запись CRC 
	//

	// образа (cfe+sqsh+kernel)
	printf("[i] update image CRC...\n");
	updateCRC(buf, TAG_LEN - 2*TOKEN_LEN, crc_image);
	// файловой системы
	printf("[i] update sqsh CRC...\n");
	updateCRC(buf, TAG_LEN - 2*TOKEN_LEN + 4, crc_rootfs);
	// ядра
	printf("[i] update kernel CRC...\n");
	updateCRC(buf, TAG_LEN - 2*TOKEN_LEN + 8, crc_kernel);

	//
	// теперь, с новыми CRC в заголовке - нужно
	// пересчитать CRC самого заголовка
	//

	// рассчёт CRC заголовка
	crc_bcm = getCRC32String((uint8_t *) (buf), size_bcm-TOKEN_LEN, header_crc);
	printf("[i] CRC header\t\t: 0x%s\n", header_crc);
	// обновляем
	printf("[i] update header CRC...\n");
	updateCRC(buf, TAG_LEN - TOKEN_LEN, crc_bcm);

	printf("[i] write file: %s\n", result_file);
	//
	// записываем результат в файл
	//
	fwrite(buf, size_result, 1, fresult);

	// закрытие файлов
	fclose(fbcm);
	fclose(fcfe);
	fclose(fsqsh);
	fclose(fkernel);

	fclose(fresult);

	printf("[i] Done.\n");
	info();
	return 0;
}