Welcome to mirror list, hosted at ThFree Co, Russian Federation.

v_func_storage.c « dist « verse « extern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 86c7815c2af4a550408756b4c3f8047fbd6f3d7f (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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
 * 
*/

#include <stdio.h>
#include <stdlib.h>
#include "verse_header.h"
#include "v_pack.h"
#include "v_cmd_gen.h"
#include "v_connection.h"
#if !defined(V_GENERATE_FUNC_MODE)
#include "verse.h"
#include "v_cmd_buf.h"
#include "v_network_out_que.h"

#define V_FS_MAX_CMDS	256

extern void init_pack_and_unpack(void);

static struct {
	unsigned int	(*unpack_func[V_FS_MAX_CMDS])(const char *data, size_t length);
	void		*pack_func[V_FS_MAX_CMDS];
	void		*user_func[V_FS_MAX_CMDS];
	void		*user_data[V_FS_MAX_CMDS];
	void		*alias_pack_func[V_FS_MAX_CMDS];
	void		*alias_user_func[V_FS_MAX_CMDS];
	void		*alias_user_data[V_FS_MAX_CMDS];
	boolean		call;
} VCmdData;

static boolean v_fs_initialized = FALSE;

extern void verse_send_packet_ack(uint32 packet_id);
extern void callback_send_packet_ack(void *user, uint32 packet_id);
extern void verse_send_packet_nak(uint32 packet_id);
extern void callback_send_packet_nak(void *user, uint32 packet_id);

void v_fs_init(void)
{
	unsigned int i;
	if(v_fs_initialized)
		return;
	for(i = 0; i < V_FS_MAX_CMDS; i++)
	{
		VCmdData.unpack_func[i] = NULL;
		VCmdData.pack_func[i] = NULL;
		VCmdData.user_func[i] = NULL;
		VCmdData.user_data[i] = NULL;
		VCmdData.alias_pack_func[i] = NULL;
		VCmdData.alias_user_func[i] = NULL;
		VCmdData.alias_user_data[i] = NULL;
	}
	#if !defined(V_GENERATE_FUNC_MODE)
	init_pack_and_unpack();
	#endif
	for(i = 0; i < V_FS_MAX_CMDS && VCmdData.pack_func[i] != verse_send_packet_ack; i++);
	VCmdData.user_func[i] = callback_send_packet_ack;
	for(i = 0; i < V_FS_MAX_CMDS && VCmdData.pack_func[i] != verse_send_packet_nak; i++);
	VCmdData.user_func[i] = callback_send_packet_nak;

	v_fs_initialized = TRUE;
}


void v_fs_add_func(unsigned int cmd_id, unsigned int (*unpack_func)(const char *data, size_t length), void *pack_func, void *alias_func)
{
	VCmdData.unpack_func[cmd_id] = unpack_func;
	VCmdData.pack_func[cmd_id] = pack_func;
	VCmdData.alias_pack_func[cmd_id] = alias_func;
}

void *v_fs_get_user_func(unsigned int cmd_id)
{
/*	if(VCmdData.call)*/
		return VCmdData.user_func[cmd_id];
	return NULL;
}

void *v_fs_get_user_data(unsigned int cmd_id)
{
	return VCmdData.user_data[cmd_id];
}

void *v_fs_get_alias_user_func(unsigned int cmd_id)
{
/*	if(VCmdData.call)*/
		return VCmdData.alias_user_func[cmd_id];
	return NULL;
}

void *v_fs_get_alias_user_data(unsigned int cmd_id)
{
	return VCmdData.alias_user_data[cmd_id];
}

void verse_callback_set(void *command, void *callback, void *user)
{
	unsigned int i;
	if(!v_fs_initialized)
		v_fs_init();

	for(i = 0; i < V_FS_MAX_CMDS; i++)
	{
		if(VCmdData.pack_func[i] == command)
		{
			VCmdData.user_data[i] = user;
			VCmdData.user_func[i] = callback;
			return;
		}
		if(VCmdData.alias_pack_func[i] == command)
		{
			VCmdData.alias_user_data[i] = user;
			VCmdData.alias_user_func[i] = callback;
			return;
		}
	}
}

/* Do we accept incoming connections, i.e. are we a host implementation? */
boolean v_fs_func_accept_connections(void)
{
	return VCmdData.user_func[0] != NULL;
}

/* Inspect beginning of packet, looking for ACK or NAK commands. */
void v_fs_unpack_beginning(const uint8 *data, unsigned int length)
{
	uint32 id, i = 4;
	uint8 cmd_id;

	i += vnp_raw_unpack_uint8(&data[i], &cmd_id);
	while(i < length && (cmd_id == 7 || cmd_id == 8))
	{
		i += vnp_raw_unpack_uint32(&data[i], &id);
		if(cmd_id == 7)
			callback_send_packet_ack(NULL, id);
		else
			callback_send_packet_nak(NULL, id);
		i += vnp_raw_unpack_uint8(&data[i], &cmd_id);
	}
}

void v_fs_unpack(uint8 *data, unsigned int length)
{
	uint32 i, output, pack_id;
	uint8 cmd_id, last = 255;

	i = vnp_raw_unpack_uint32(data, &pack_id); /* each packet starts with a 32 bit id */
	vnp_raw_unpack_uint8(&data[i], &cmd_id);
	while(i < length && (cmd_id == 7 || cmd_id == 8))
	{
		i += 5;
		vnp_raw_unpack_uint8(&data[i], &cmd_id);
	}
	while(i < length)
	{
		i += vnp_raw_unpack_uint8(&data[i], &cmd_id);
		if(VCmdData.unpack_func[cmd_id] != NULL)
		{
			VCmdData.call = TRUE;
			output = VCmdData.unpack_func[cmd_id](&data[i], length - i);
			if(output == (unsigned int) -1)	/* Can this happen? Should be size_t or int, depending. */
			{
				printf("** Aborting decode, command %u unpacker returned failure\n", cmd_id);
/*				verse_send_packet_nak(pack_id);*/
				return;
			}
			last = cmd_id;
			i += output;
		}
		else	/* If unknown command byte was found, complain loudly and stop parsing packet. */
		{
			size_t	j;

			printf("\n** Unknown command ID %u (0x%02X) encountered--aborting packet decode len=%u pos=%u last=%u\n", cmd_id, cmd_id, length, i, last);
			printf(" decoded %u bytes: ", --i);
			for(j = 0; j < i; j++)
				printf("%02X ", data[j]);
			printf("\n (packet id=%u)", pack_id);
			printf(" remaining %u bytes: ", length - i);
			for(j = i; j < length; j++)
				printf("%02X ", data[j]);
			printf("\n");
/*			*(char *) 0 = 0;*/
			break;
		}
	}
/*	if(expected != NULL)
		verse_send_packet_ack(pack_id);*/
}

extern unsigned int v_unpack_connection(const char *data, size_t length);

#endif