summaryrefslogtreecommitdiff
path: root/host/src/sci_msg.c
blob: f685c41eeedb3e1a9122db3509b09db0d0748352 (plain)
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
 
/**
 * \file    sci_msg.c
 * \brief   The sci message management functions
 * \ingroup host
 *
 * This file provide sci message management functions
 *
 * \todo   
 */

#include "common/std.h"
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "host/sci.h"
#ifndef UNIT_TEST
#include "host/syscall.h"
#else /* UNIT_TEST */
#include <unistd.h>
#endif /* UNIT_TEST */

/**
 * create a new sci message.
 * \param size max size of message
 * \return the new sci msg, NULL if failed, with errno
 * - EINVAL is size < sizeof(sci_msg_hdr_t) or > SCI_MSG_MAX_SIZE
 */
sci_msg_t *sci_msg_new(int max_size)
{
    /* maybe will not be implemented */
    return NULL;
}

/**
 * sci message destruction with memory freeing.
 * \param msg msg context to destroy
 */
void sci_msg_free(sci_msg_t *msg)
{
    /* maybe will not be implemented */
    return;
}

/**
 * sci message init if a static msg structure is used (instead of dynamic).
 * \param msg pointer to msg context to initialize
 * \param buffer pointer to a data buffer with allocated space
 * \param max_size buffer max size
 * \return 0 if ok, -1 if failed with errno=
 * - EINVAL if msg of buffer is NULL, or if size is < sizeof(sci_msg_hdr_t) or >= SCI_MSG_MAX_SIZE
 */
int sci_msg_init(sci_msg_t *msg, unsigned char *buffer, int max_size)
{
    DBG_ASSERT(msg);
    DBG_ASSERT(buffer);
    DBG_ASSERT(max_size >= (int)sizeof(sci_msg_hdr_t));
    DBG_ASSERT(max_size <= SCI_MSG_MAX_SIZE);
    if((msg == NULL)
        || (buffer == NULL)
        || (max_size < (int)sizeof(sci_msg_hdr_t))
        || (max_size > SCI_MSG_MAX_SIZE))
    {
        errno = EINVAL;
        return -1;
    }
    
    /* init structure */
    /* structure is managed through push/pop calls; 
     * 'data_begin' points to the beginning accessible data, and is decremented while new data are pushed
     * 'length' give current size of stored data
     */
    memset(msg, '\0', sizeof(sci_msg_t));
    msg->data = buffer;
    msg->max_size = max_size;
    msg->data_begin = msg->data + max_size;
    msg->data_end = msg->data_begin;
    return 0;
} 

/**
 * sci message adding of new data with pointers update.
 * \param msg msg where to add data
 * \param length length of data to add
 * \return length if ok, -1 if failed with errno=
 * - EINVAL if msg is NULL
 * - ENOSPC if length is bigger than free space into buffer
 */
int sci_msg_push(sci_msg_t *msg, int length)
{
    DBG_ASSERT(msg);
    DBG_ASSERT(length >= 0);
    if((msg == NULL)
        || (length < 0))
    {
        errno = EINVAL;
        return -1;
    }
    
    if(length > msg->max_size - msg->length)
    {
        errno = ENOSPC;
        return -1;
    }
    
    msg->data_begin -= length;
    msg->length += length;
    
    return length;
}

/**
 * sci message removing of data with pointers update.
 * \param msg msg where to remove data
 * \param length length of data to remove
 * \return number of bytes stored, -1 if failed with errno=
 * - EINVAL if msg or data is NULL
 */
int sci_msg_pop(sci_msg_t *msg, int length)
{
    int final_len;
    
    DBG_ASSERT(msg);
    DBG_ASSERT(length >= 0);
    if((msg == NULL)
        || (length < 0))
    {
        errno = EINVAL;
        return -1;
    }
    
    if(length >= msg->length)
        final_len = msg->length;
    else
        final_len = length;
        
    msg->length -= final_len;
    msg->data_begin += final_len;
    
    return final_len;
}

void sci_msg_dump(sci_msg_t *msg, int fd, char *buffer, int size)
{
    if((msg == NULL)
        || (fd < 0)
        || (size <= 0))
        return;
    buffer[size - 1] = '\0';
    snprintf(buffer, size - 1, "sci_msg(%p): sci=%p, hdr=%p ", msg, msg->sci_hdr, msg->hdr.generic);
    write(fd, buffer, strlen(buffer));
    snprintf(buffer, size - 1, "data=%p, begin=%p, end=%p, length=%d, max_size=%d\n",
        msg->data, msg->data_begin, msg->data_end,
        msg->length, msg->max_size);
    write(fd, buffer, strlen(buffer));
    return;
}