示例#1
0
/**
 * DEPRECATED FUCNTIONS
 * To read the tag string from device you shoul use the keytag_recv
 * fuction, that return the string if we had received it.
 */
void keytag_poll(struct TagPacket *pkt)
{
#warning __FILTER_NEXT_WARNING__
#warning keytag_poll function is depreca use keytag_recv instead
    uint8_t buf[CONFIG_TAG_MAX_LEN];
    int len;
    if ((len = keytag_recv(pkt, buf, sizeof(buf))) != EOF)
        kfile_write(pkt->host, buf, len);
}
示例#2
0
/**
 * Generic putc() implementation using \a fd->write.
 */
int kfile_putc(int _c, struct KFile *fd)
{
	unsigned char c = (unsigned char)_c;

	if (kfile_write(fd, &c, sizeof(c)) == sizeof(c))
		return (int)((unsigned char)_c);
	else
		return EOF;
}
示例#3
0
/**
 * KFile read/write subtest.
 * Try to write/read in the same \a f file location \a size bytes.
 * \return true if all is ok, false otherwise
 * \note Restore file position at exit (if no error)
 * \note Test buffer \a buf must be filled with
 * the following statement:
 * \code
 * buf[i] = i & 0xff
 * \endcode
 */
static bool kfile_rwTest(KFile *f, uint8_t *buf, size_t size)
{
	/*
	 * Write test buffer
	 */
	if (kfile_write(f, buf, size) != size)
	{
		LOG_ERR("error writing buf");
		return false;
	}

	kfile_seek(f, -(kfile_off_t)size, KSM_SEEK_CUR);

	/*
	 * Reset test buffer
	 */
	memset(buf, 0, size);

	/*
	 * Read file in test buffer
	 */
	if (kfile_read(f, buf, size) != size)
	{
		LOG_ERR("error reading buf");
		return false;
	}


	kfile_seek(f, -(kfile_off_t)size, KSM_SEEK_CUR);

	/*
	 * Check test result
	 */
	for (size_t i = 0; i < size; i++)
	{
		if (buf[i] != (i & 0xff))
		{
			LOG_ERR("error comparing at index [%d] read [%02x] expected [%02x]\n", i, buf[i], i);
			return false;
		}
	}

	return true;
}
示例#4
0
kfile_off_t kfile_copy(KFile *src, KFile *dst, kfile_off_t size)
{
	char buf[32];
	kfile_off_t cp_len = 0;

	while (size)
	{
		size_t len = MIN(sizeof(buf), (size_t)size);
		if (kfile_read(src, buf, len) != len)
			break;

		size_t wr_len = kfile_write(dst, buf, len);
		cp_len += wr_len;
		size -= len;

		if (wr_len != len)
			break;
	}

	return cp_len;
}
示例#5
0
文件: gsm.c 项目: derkling/adcontrol
static int8_t _gsmWriteLine(const char *cmd)
{
	size_t i;

	// NOTE: debugging should no be mixed to modem command and response to
	// avoid timeing issues and discrepancy between debug and release
	// versions
	gsmDebug("TX [%s]\n", cmd);

	// Purge any buffered data before sending a new command
	ser_purge(gsm);
	// Clear error flags
	ser_setstatus(gsm, 0);

	// Sending the AT command
	WATCHDOG_RESET();
	for (i=0; cmd[i]!='\0'; i++) {
		kfile_putc(cmd[i], &(gsm->fd));
		WATCHDOG_RESET();
	}
	kfile_write(&(gsm->fd), "\r\n", 2);

	return i;
}
示例#6
0
/**
 * Write \a _buf in serial flash memory
 *
 * Before to write data into flash we must enable
 * memory writing. To do this we send a WRE command opcode.
 * After this command the flash is ready to be write, and so
 * we send a PROGRAM opcode followed to 3 byte of
 * address memory, at the end of last address byte
 * we can send the data.
 * When we finish to send all data, we disable cs
 * and flash write received data bytes on its memory.
 *
 * \note: WARNING: you could write only on erased memory section!
 * Each write time you could write max a memory page size,
 * because if you write more than memory page size the
 * address roll over to first byte of page.
 *
 * \return the number of bytes write.
 */
static size_t flash25_write(struct KFile *_fd, const void *_buf, size_t size)
{
	flash25Offset_t offset;
	flash25Size_t total_write = 0;
	flash25Size_t wr_len;
	const uint8_t *data = (const uint8_t *) _buf;

	Flash25 *fd = FLASH25_CAST(_fd);

	ASSERT(fd->fd.seek_pos + (kfile_off_t)size <= fd->fd.size);

	size = MIN((kfile_off_t)size, fd->fd.size - fd->fd.seek_pos);

	while (size)
	{
		offset = fd->fd.seek_pos % (flash25Size_t)FLASH25_PAGE_SIZE;
		wr_len = MIN((flash25Size_t)size, FLASH25_PAGE_SIZE - (flash25Size_t)offset);

		kprintf("[seek_pos-<%lu>, offset-<%d>]\n", fd->fd.seek_pos, offset);

		/*
		 * We check serial flash memory state, and wait until ready-flag
		 * is high.
		 */
		flash25_waitReady(fd);

		/*
		 * Start write cycle.
		 * We could write only data not more long than one
		 * page size.
		 *
		 * To write on serial flash memory we must first
		 * enable write with a WREN opcode command, before
		 * the PROGRAM opcode.
		 *
		 * \note: the same byte cannot be reprogrammed without
		 * erasing the whole sector first.
		 */
		flash25_sendCmd(fd, FLASH25_WREN);

		SS_ACTIVE();
		kfile_putc(FLASH25_PROGRAM, fd->channel);

		/*
		 * Address that we want to write.
		 */
		kfile_putc((fd->fd.seek_pos >> 16) & 0xFF, fd->channel);
		kfile_putc((fd->fd.seek_pos >> 8) & 0xFF, fd->channel);
		kfile_putc(fd->fd.seek_pos & 0xFF, fd->channel);

		kfile_write(fd->channel, data, wr_len);

		SS_INACTIVE();

		data += wr_len;
		fd->fd.seek_pos += wr_len;
		size -= wr_len;
		total_write += wr_len;
	}

	kprintf("written %lu bytes\n", total_write);
	return total_write;
}
示例#7
0
/**
 * \brief Receive a file using the XModem protocol.
 *
 * \param ch Channel to use for transfer
 * \param fd Destination file
 *
 * \note This function allocates a large amount of stack (\see XM_BUFSIZE).
 */
bool xmodem_recv(KFile *ch, KFile *fd)
{
    char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
    int c, i, blocksize;
    int blocknr = 0, last_block_done = 0, retries = 0;
    char *buf;
    uint8_t checksum;
    uint16_t crc;
    bool purge = false;
    bool usecrc = true;


    LOG_INFO("Starting Transfer...\n");
    purge = true;
    kfile_clearerr(ch);

    /* Send initial NAK to start transmission */
    for(;;)
    {
        if (XMODEM_CHECK_ABORT)
        {
            kfile_putc(XM_CAN, ch);
            kfile_putc(XM_CAN, ch);
            LOG_INFO("Transfer aborted\n");
            return false;
        }

        /*
         * Discard incoming input until a timeout occurs, then send
         * a NAK to the transmitter.
         */
        if (purge)
        {
            purge = false;

            if (kfile_error(ch))
            {
                LOG_ERR("Retries %d\n", retries);
            }

            kfile_resync(ch, 200);
            retries++;

            if (retries >= CONFIG_XMODEM_MAXRETRIES)
            {
                kfile_putc(XM_CAN, ch);
                kfile_putc(XM_CAN, ch);
                LOG_INFO("Transfer aborted\n");
                return false;
            }

            /* Transmission start? */
            if (blocknr == 0)
            {
                if (retries < CONFIG_XMODEM_MAXCRCRETRIES)
                {
                    LOG_INFO("Request Tx (CRC)\n");
                    kfile_putc(XM_C, ch);
                }
                else
                {
                    /* Give up with CRC and fall back to checksum */
                    usecrc = false;
                    LOG_INFO("Request Tx (BCC)\n");
                    kfile_putc(XM_NAK, ch);
                }
            }
            else
                kfile_putc(XM_NAK, ch);
        }

        switch (kfile_getc(ch))
        {
#if XM_BUFSIZE >= 1024
        case XM_STX:  /* Start of header (1024-byte block) */
            blocksize = 1024;
            goto getblock;
#endif

        case XM_SOH:  /* Start of header (128-byte block) */
            blocksize = 128;
            /* Needed to avoid warning if XM_BUFSIZE < 1024 */

getblock:
            /* Get block number */
            c = kfile_getc(ch);

            /* Check complemented block number */
            if ((~c & 0xff) != kfile_getc(ch))
            {
                LOG_WARN("Bad blk (%d)\n", c);
                purge = true;
                break;
            }

            /* Determine which block is being sent */
            if (c == (blocknr & 0xff))
            {
                /* Last block repeated */
                LOG_INFO("Repeat blk %d\n", blocknr);
            }
            else if (c == ((blocknr + 1) & 0xff))
            {
                /* Next block */
                LOG_INFO("Recv blk %d\n", ++blocknr);
            }
            else
            {
                /* Sync lost */
                LOG_WARN("Sync lost (%d/%d)\n", c, blocknr);
                purge = true;
                break;
            }

            buf = block_buffer;	/* Reset pointer to start of buffer */
            checksum = 0;
            crc = 0;
            for (i = 0; i < blocksize; i++)
            {
                if ((c = kfile_getc(ch)) == EOF)
                {
                    purge = true;
                    break;
                }

                /* Store in buffer */
                *buf++ = (char)c;

                /* Calculate block checksum or CRC */
                if (usecrc)
                    crc = UPDCRC16(c, crc);
                else
                    checksum += (char)c;
            }

            if (purge)
                break;

            /* Get the checksum byte or the CRC-16 MSB */
            if ((c = kfile_getc(ch)) == EOF)
            {
                purge = true;
                break;
            }

            if (usecrc)
            {
                crc = UPDCRC16(c, crc);

                /* Get CRC-16 LSB */
                if ((c = kfile_getc(ch)) == EOF)
                {
                    purge = true;
                    break;
                }

                crc = UPDCRC16(c, crc);

                if (crc)
                {
                    LOG_ERR("Bad CRC: %04x\n", crc);
                    purge = true;
                    break;
                }
            }
            /* Compare the checksum */
            else if (c != checksum)
            {
                LOG_ERR("Bad sum: %04x/%04x\n", checksum, c);
                purge = true;
                break;
            }

            /*
             * Avoid flushing the same block twice.
             * This could happen when the sender does not receive our
             * acknowledge and resends the same block.
             */
            if (last_block_done < blocknr)
            {
                /* Call user function to flush the buffer */
                if (kfile_write(fd, block_buffer, blocksize))
                {
                    /* Acknowledge block and clear error counter */
                    kfile_putc(XM_ACK, ch);
                    retries = 0;
                    last_block_done = blocknr;
                }
                else
                {
                    /* User callback failed: abort transfer immediately */
                    retries = CONFIG_XMODEM_MAXRETRIES;
                    purge = true;
                }
            }
            break;

        case XM_EOT:	/* End of transmission */
            kfile_putc(XM_ACK, ch);
            LOG_INFO("Transfer completed\n");
            return true;

        case EOF: /* Timeout or serial error */
            purge = true;
            break;

        default:
            LOG_INFO("Skipping garbage\n");
            purge = true;
            break;
        }
    } /* End forever */
}
示例#8
0
文件: namei.c 项目: CPonty/ext3301-fs
/*
 * ext3301: modified to encrypt/decrypt files moving to/from
 * 	an encrypted folder.
 * Rename still succeeds if an encrypt/decrypt operation fails.
 */
static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
	struct inode * new_dir,	struct dentry * new_dentry )
{
	struct inode * old_inode = old_dentry->d_inode;
	struct inode * new_inode = new_dentry->d_inode;
	struct page * dir_page = NULL;
	struct ext2_dir_entry_2 * dir_de = NULL;
	struct page * old_page;
	struct ext2_dir_entry_2 * old_de;
	int err = -ENOENT;

	bool is_encryptable, src_encrypt, dest_encrypt;
	int i;
	struct file * fcrypt;
	ssize_t nchunk, nread, nwritten;
	loff_t fpos, fseekpos;
	unsigned int fsize, fremaining;
	char * buf, * strbuf1, * strbuf2, * path_src, * path_dest;
	size_t blocksize = INODE_BLKSIZE(old_inode);

	//

	dquot_initialize(old_dir);
	dquot_initialize(new_dir);

	old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page);
	if (!old_de)
		goto out;

	if (S_ISDIR(old_inode->i_mode)) {
		err = -EIO;
		dir_de = ext2_dotdot(old_inode, &dir_page);
		if (!dir_de)
			goto out_old;
	}

	if (new_inode) {
		struct page *new_page;
		struct ext2_dir_entry_2 *new_de;

		err = -ENOTEMPTY;
		if (dir_de && !ext2_empty_dir (new_inode))
			goto out_dir;

		err = -ENOENT;
		new_de = ext2_find_entry (new_dir, &new_dentry->d_name, &new_page);
		if (!new_de)
			goto out_dir;
		ext2_set_link(new_dir, new_de, new_page, old_inode, 1);
		new_inode->i_ctime = CURRENT_TIME_SEC;
		if (dir_de)
			drop_nlink(new_inode);
		inode_dec_link_count(new_inode);
	} else {
		err = ext2_add_link(new_dentry, old_inode);
		if (err)
			goto out_dir;
		if (dir_de)
			inode_inc_link_count(new_dir);
	}

	// allocate buffers
	strbuf1 = kmalloc((size_t)512, GFP_KERNEL);
	strbuf2 = kmalloc((size_t)512, GFP_KERNEL);
	buf = kmalloc(blocksize, GFP_KERNEL);
	if (!buf || !strbuf1 || !strbuf2)
		return -ENOMEM;

	// check if the source XOR destination lie under /encrypt,
	// 	and both entries are regular or immediate files
	is_encryptable = (I_ISIM(old_inode) || I_ISREG(old_inode));
	src_encrypt = ext3301_isencrypted(old_dentry);
	dest_encrypt = ext3301_isencrypted(new_dentry);
	path_src  = ext3301_getpath(old_dentry, strbuf1, blocksize);
	path_dest = ext3301_getpath(new_dentry, strbuf2, blocksize);

	// decide whether to encrypt
	dbg(KERN_DEBUG "rename (%s --> %s)\n", path_src, path_dest);
	if (is_encryptable) {
		dbg_cr(KERN_DEBUG "- File encryptable type (regular/immediate)\n");
		if (src_encrypt && dest_encrypt) {
			dbg_cr(KERN_DEBUG "- File moving inside /encrypt (no change))\n");
		} else if (src_encrypt) {
			dbg_cr(KERN_DEBUG "- File moving out of /encrypt. Decrypting..\n");
			goto cryptstart;
		} else if (dest_encrypt) {
			dbg_cr(KERN_DEBUG "- File moving into /encrypt. Encrypting..\n");
			goto cryptstart;
		} else {
			dbg_cr(KERN_DEBUG "- Src/dest directories not encryptable\n");
		}
	} else {
		dbg_cr(KERN_DEBUG "- File not an encryptable type\n");
	}
	goto cryptdone;

/* encrypt/decrypt file */
cryptstart: 
	// open file
	if (!path_src)
		goto cryptfail;
	fcrypt = kfile_open(path_src, O_RDWR);
	if (!fcrypt)
		goto cryptfail;
	fsize = FILP_FSIZE(fcrypt);
	fremaining = fsize;
	fpos = 0;
	fseekpos = 0;
	dbg_cr(KERN_DEBUG " - Opened %s (Fsize: %d)\n", 
		FILP_NAME(fcrypt), fsize);
	// special case: nothing to encrypt
	if (fsize==0) 
		goto cryptclose;
	// loop: read, encrypt, write
	while (fremaining > 0) {
		// choose a chunk size
		nchunk = (fremaining > blocksize ? blocksize : (ssize_t)fremaining);
		dbg_cr(KERN_DEBUG " - Starting a %d-byte chunk at pos %u.\n", 
			(int)nchunk, (unsigned int)fpos);
		// read a chunk; make sure we read all bytes requested.
		fpos = fseekpos;
		nread = kfile_read(fcrypt, buf, (size_t)nchunk, &fpos);
		//	this inequality covers error conditions (nread<0) and 
		//	partial reads (0<=nread<=nchunk && nread != nchunk)
		if (nread != nchunk) {
			kfile_close(fcrypt);
			goto cryptfail;
		}
		// encrypt the buffer
		for (i=0; i<nchunk; i++)
			buf[i] ^= crypter_key;
		// write the chunk back
		fpos = fseekpos;
		nwritten = kfile_write(fcrypt, buf, (size_t)nchunk, &fpos);
		if (nwritten != nchunk) {
			kfile_close(fcrypt);
			goto cryptfail;
		}
		// move the file marker forward, decrease the #bytes remaining
		fseekpos += nchunk;
		fremaining -= nchunk;
	}
	// sync the read/write operations to disk. Very important!
	kfile_sync(fcrypt);

cryptclose:
	kfile_close(fcrypt);
	goto cryptdone;

cryptfail:
	// encrypt/decrypt failed
	if (dest_encrypt)
		printk(KERN_WARNING "Crypting file entering /%s failed: ino %lu\n",
				crypter_dir, INODE_INO(old_inode));
	else if (src_encrypt)
		printk(KERN_WARNING "Decrypting file leaving /%s failed: ino %lu\n",
				crypter_dir, INODE_INO(old_inode));
	goto cryptdone;

cryptdone:
	/*
	 * Like most other Unix systems, set the ctime for inodes on a
 	 * rename.
	 */
	old_inode->i_ctime = CURRENT_TIME_SEC;
	mark_inode_dirty(old_inode);

	ext2_delete_entry (old_de, old_page);

	if (dir_de) {
		if (old_dir != new_dir)
			ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0);
		else {
			kunmap(dir_page);
			page_cache_release(dir_page);
		}
		inode_dec_link_count(old_dir);
	}
	goto out_free;

out_dir:
	if (dir_de) {
		kunmap(dir_page);
		page_cache_release(dir_page);
	}
out_old:
	kunmap(old_page);
	page_cache_release(old_page);
out:
	return err;
out_free:
	// free buffers
	kfree(strbuf1);
	kfree(strbuf2);
	kfree(buf);
	return 0;
}
示例#9
0
/**
 * KFile read/write test.
 * This function write and read \a test_buf long \a size
 * on \a fd handler.
 * \a save_buf can be NULL or a buffer where to save previous file content.
 */
int kfile_testRunGeneric(KFile *fd, uint8_t *test_buf, uint8_t *save_buf, size_t size)
{

	/*
	 * Part of test buf size that you would write.
	 * This var is used in test 3 to check kfile_write
	 * when writing beyond filesize limit.
	 */
	kfile_off_t len = size / 2;


	/* Fill test buffer */
	for (size_t i = 0; i < size; i++)
		test_buf[i] = (i & 0xff);

	/*
	 * If necessary, user can save content,
	 * for later restore.
	 */
	if (save_buf)
	{
		LOG_INFO("Saved content..form [%ld] to [%ld]\n", fd->seek_pos, fd->seek_pos + size);
		kfile_read(fd, save_buf, size);
	}

	/* TEST 1 BEGIN. */
	LOG_INFO("Test 1: write from pos 0 to [%ld]\n", (long)size);

	/*
	 * Seek to addr 0.
	 */
	if (kfile_seek(fd, 0, KSM_SEEK_SET) != 0)
		goto kfile_test_end;

	/*
	 * Test read/write to address 0..size
	 */
	if (!kfile_rwTest(fd, test_buf, size))
		goto kfile_test_end;

	LOG_INFO("Test 1: ok!\n");

	/*
	 * Restore previous read content.
	 */
	if (save_buf)
	{
		kfile_seek(fd, 0, KSM_SEEK_SET);

		if (kfile_write(fd, save_buf, size) != size)
			goto kfile_test_end;

		LOG_INFO("Restore content..form [%ld] to [%ld]\n", fd->seek_pos, fd->seek_pos + size);
	}
	/* TEST 1 END. */

	/* TEST 2 BEGIN. */
	LOG_INFO("Test 2: write from pos [%ld] to [%ld]\n", fd->size/2 , fd->size/2 + size);

	/*
	 * Go to half test size.
	 */
	kfile_seek(fd, (fd->size / 2), KSM_SEEK_SET);

	/*
	 * If necessary, user can save content
	 * for later restore.
	 */
	if (save_buf)
	{
		kfile_read(fd, save_buf, size);
		kfile_seek(fd, -(kfile_off_t)size, KSM_SEEK_CUR);
		LOG_INFO("Saved content..form [%ld] to [%ld]\n", fd->seek_pos, fd->seek_pos + size);
	}

	/*
	 * Test read/write to address filesize/2 ... filesize/2 + size
	 */
	if (!kfile_rwTest(fd, test_buf, size))
		goto kfile_test_end;

	LOG_INFO("Test 2: ok!\n");

	/*
	 * Restore previous content.
	 */
	if (save_buf)
	{
		kfile_seek(fd, -(kfile_off_t)size, KSM_SEEK_CUR);

		if (kfile_write(fd, save_buf, size) != size)
			goto kfile_test_end;

		LOG_INFO("Restore content..form [%ld] to [%ld]\n", fd->seek_pos, fd->seek_pos + size);
	}

	/* TEST 2 END. */

	/* TEST 3 BEGIN. */
	LOG_INFO("Test 3: write outside of fd->size limit [%ld]\n", fd->size);

	/*
	 * Go to the Flash end
	 */
	kfile_seek(fd, -len, KSM_SEEK_END);

	/*
	 * If necessary, user can save content,
	 * for later restore.
	 */
	if (save_buf)
	{
		kfile_read(fd, save_buf, len);
		kfile_seek(fd, -len, KSM_SEEK_CUR);
		LOG_INFO("Saved content..form [%ld] to [%ld]\n", fd->seek_pos, fd->seek_pos + len);
	}

	/*
	 * Test read/write to address (filesize - size) ... filesize
	 */
	if (kfile_rwTest(fd, test_buf, size))
		goto kfile_test_end;

	kprintf("Test 3: ok!\n");

	/*
	 * Restore previous read content
	 */
	if (save_buf)
	{
		kfile_seek(fd, -len, KSM_SEEK_END);

		if ((kfile_off_t)kfile_write(fd, save_buf, len) != len)
			goto kfile_test_end;

		LOG_INFO("Restore content..form [%ld] to [%ld]\n", fd->seek_pos, fd->seek_pos + len);
	}

	/* TEST 3 END. */

	kfile_close(fd);
	return 0;

kfile_test_end:
	kfile_close(fd);
	LOG_ERR("One kfile_test failed!\n");
	return EOF;
}
示例#10
0
文件: main.c 项目: mtarek/BeRTOS
int main(void)
{
	// SD fat filesystem context
	FATFS fs;

	// Context files that we would manage
	FatFile ini_file;
	FatFile log_file;

	init();

	LOG_INFO("SD fat example project %s: %d times\n", VERS_HOST, VERS_BUILD);

	while (1)
	{
		bool sd_ok = true;
		FRESULT result;

		// Setting info
		INISetting ini_set;
		memset(&ini_set, 0, sizeof(ini_set));

		sd_ok = sd_init(&spi_dma.fd);

		if (sd_ok)
		{
			LOG_INFO("Mount FAT filesystem.\n");
			if ((result = f_mount(0, &fs)) != FR_OK)
			{
				LOG_ERR("Mounting FAT volumes error[%d]\n", result);
				sd_ok = false;
			}

			LOG_INFO("Read setting from ini file: %s\n", INI_FILE_NAME);
			if (sd_ok && ((result = fatfile_open(&ini_file, INI_FILE_NAME, FA_READ)) != FR_OK))
			{
				LOG_ERR("Could not open ini file: %s error[%d,]\n", INI_FILE_NAME, result);
				sd_ok = false;
			}

			if (sd_ok)
			{
				/*
				 * If sd is ok, we read all setting from INI file.
				 * NOTE: if one ini key or section was not found into INI
				 * file, the iniparser return the defaul value.
				 */
				ini_getString(&ini_file.fd, LOG_SECTION, LOG_NAME_KEY, "default.log", ini_set.name, sizeof(ini_set.name));
				LOG_INFO("Log file name [%s]\n", ini_set.name);

				char tmp[25];
				ini_getString(&ini_file.fd, LOG_SECTION, LOG_ON_SERIAL,   "1", tmp, sizeof(tmp));
				ini_set.log_on_serial = atoi(tmp);
				LOG_INFO("Log serial [%d]\n", ini_set.log_on_serial);
				ini_getString(&ini_file.fd, LOG_SECTION, LOG_ON_FILE,     "1", tmp, sizeof(tmp));
				ini_set.log_on_file = atoi(tmp);
				LOG_INFO("Log sd [%d]\n", ini_set.log_on_file);
				ini_getString(&ini_file.fd, LOG_SECTION, LOG_SAMPLE_TIME, "500", tmp, sizeof(tmp));
				ini_set.sample_time = atoi(tmp);
				LOG_INFO("Sample time [%ld]\n", ini_set.sample_time);

				ini_getString(&ini_file.fd, SERIAL_LOG, SERIAL_PORT, "0", tmp, sizeof(tmp));
				ini_set.port = atoi(tmp);
				LOG_INFO("Serial port [%d]\n", ini_set.port);
				ini_getString(&ini_file.fd, SERIAL_LOG, SERIAL_BAUD, "115200", tmp, sizeof(tmp));
				ini_set.baud = atoi(tmp);
				LOG_INFO("Serial buad [%d]\n", ini_set.baud);

				ini_getString(&ini_file.fd, LOG_FORMAT_SEC, FORMAT_LINE_HEADER, "BeRTOS: ", ini_set.line_header, sizeof(ini_set.line_header));
				LOG_INFO("Serial line header[%s]\n", ini_set.line_header);

				ini_getString(&ini_file.fd, LOG_FORMAT_SEC, FORMAT_FIELD_SEP, ",", ini_set.field_sep, sizeof(ini_set.field_sep));
				LOG_INFO("Serial char sep[%s]\n", ini_set.field_sep);

				ini_getString(&ini_file.fd, TEMPERATURE, TEMP_UNIT_LABEL, "C", ini_set.temp_unit_label, sizeof(ini_set.temp_unit_label));
				LOG_INFO("Temp unit label[%s]\n", ini_set.temp_unit_label);

				ini_getString(&ini_file.fd, PRESSURE, PRESS_UNIT_LABEL, "hPa", ini_set.press_unit_label, sizeof(ini_set.press_unit_label));
				LOG_INFO("Press unit label[%s]\n", ini_set.press_unit_label);

				ini_getString(&ini_file.fd, VOLTAGE, VOLTAGE_UNIT_LABEL, "V", ini_set.voltage_unit_label, sizeof(ini_set.voltage_unit_label));
				LOG_INFO("Press unit label[%s]\n", ini_set.voltage_unit_label);

			}
		}

		if (ini_set.log_on_serial)
		{
			// Init serial log port
			ser_init(&log_port, ini_set.port);
			ser_setbaudrate(&log_port, ini_set.baud);
			LOG_INFO("SERIAL init..port[%d] buad[%d]\n", ini_set.port, ini_set.baud);
		}

		char log_string[160];
		memset(log_string, 0, sizeof(log_string));

		// Supplay voltage
		uint16_t vdd = ADC_RANGECONV(adc_read(SUPPLAY_VOLTAGE_CH), 0, ADC_SUPPLAY_VOLTAGE);

		// Read temperature
		int16_t tmp = tmp123_read(&temp_sensor_bus.fd);

		// Read pressure
		uint16_t vout = ADC_RANGECONV(adc_read(PRESSURE_SENSOR_CH), 0, vdd);
		int16_t press = mpxx6115a_press(vout,  vdd);

		/*
		 * Format string whit read data
		 * line_header + temp + temp_unit_label + field_sep + press + press_unit_label + field_sep + vdd + voltage_unit_label
		 */
		int wr_len = sprintf(log_string, "%s%d.%01d%s%s%d%s%s%d.%d%s\r\n", ini_set.line_header,
																tmp / 10, ABS(tmp % 10),
																ini_set.temp_unit_label,
																ini_set.field_sep,
																press,
																ini_set.press_unit_label,
																ini_set.field_sep,
																vdd / 1000, ABS(vdd % 1000),
																ini_set.voltage_unit_label);


		/*
		 * if SD is ok, try to open log file and write our data and, only
		 * if by configuration we have enable the log on file
		 */
		if (sd_ok && ini_set.log_on_file)
		{
			// Open log file and do not overwrite the previous log file
			result = fatfile_open(&log_file, ini_set.name,  FA_OPEN_EXISTING | FA_WRITE);

			// If the log file there isn't we create the new one
			if (result == FR_NO_FILE)
			{
				result = fatfile_open(&log_file, ini_set.name,  FA_CREATE_NEW | FA_WRITE);
				LOG_INFO("Create the log file: %s\n", ini_set.name);
			}

			if ( result == FR_OK)
			{
				LOG_INFO("Opened log file '%s' size %ld\n", ini_set.name, log_file.fat_file.fsize);

				// To append data we should go to end of file before to start to write
				kfile_seek(&log_file.fd, 0, KSM_SEEK_END);

				int len = kfile_write(&log_file.fd, log_string, wr_len);

				// Flush data and close the files.
				kfile_flush(&log_file.fd);
				kfile_close(&log_file.fd);

				// Unmount always to prevent accidental sd remove.
				f_mount(0, NULL);
				LOG_INFO("Wrote [%d]\n", len);
			}
			else
			{
				LOG_ERR("Unable to open file: '%s' error[%d]\n", ini_set.name, result);
			}
		}

		// If by configuration we have enable the log on serial, we log it
		if (ini_set.log_on_serial)
			kfile_write(&log_port.fd, log_string, wr_len);

		timer_delay(ini_set.sample_time);
	}

	return 0;
}