Subversion Repositories Kolibri OS

Rev

Rev 1238 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1238 vkos 1
/***************************************************************************************************
2
 *  Copyright (C) Vasiliy Kosenko (vkos), 2009                                                     *
3
 *  Kobra is free software: you can redistribute it and/or modify it under the terms of the GNU    *
4
 *  General Public License as published by the Free Software Foundation, either version 3          *
5
 *  of the License, or (at your option) any later version.                                         *
6
 *                                                                                                 *
7
 *  Kobra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without     *
8
 *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  *
9
 *  General Public License for more details.                                                       *
10
 *                                                                                                 *
11
 *  You should have received a copy of the GNU General Public License along with Kobra.            *
12
 *  If not, see .                                                    *
13
 ***************************************************************************************************/
14
 
15
/***************************************************************************************************
16
 *  Kobra (Kolibri Bus for Reaching Applications) is daemon for advanced & easier applications     *
17
 *  communication.                                                                                 *
18
 ***************************************************************************************************/
19
 
20
#include "kobra.h"
1286 vkos 21
#include 
22
#include 
23
#include 
24
#include 
25
#include 
26
#include 
1238 vkos 27
 
28
group_list_t *main_group_list;
29
thread_list_t *main_thread_list;
30
 
31
kolibri_memarea_t main_memarea;
32
Heap memarea_heap;
33
 
34
void *return_0(Heap *wheap, int nbytes){
35
	return NULL;
36
}
37
 
38
void *memarea_alloc(int nbytes){
39
	return halMemAlloc(&memarea_heap, nbytes);
40
}
41
 
42
void memarea_free(void *addr){
43
	halMemFree(&memarea_heap, addr);
44
}
45
 
46
void main(){
47
	malloc_init();
48
 
49
	// Alloc memory for thread&group lists
50
	main_memarea = kolibri_new_named_memory(KOBRA_MEMAREA_NAME, KOBRA_MEM_SIZE, KOLIBRI_ACCESS_READ|KOLIBRI_CREATE);
51
	halMemHeapInit(&memarea_heap, &return_0, main_memarea.addr, KOBRA_MEM_SIZE);
52
 
53
	// Init main group list
54
	create_group("main");
55
	main_group_list->next = main_group_list->previos = main_group_list;
56
	main_group_list->thread_list = main_thread_list = new_thread_list(kolibri_get_my_tid());
57
	main_thread_list->next = main_thread_list->previos = main_thread_list;
58
 
1286 vkos 59
	IPCInit();
60
// 	kolibri_IPC_unlock();
1238 vkos 61
 
62
	// Set event mask
1286 vkos 63
// 	kolibri_event_set_mask(KOLIBRI_IPC_EVENT_MASK);
1238 vkos 64
 
65
	while (1) {
1286 vkos 66
		Message *msg = IPCWaitMessage(-1);
67
// 		if (kolibri_event_wait() != KOLIBRI_IPC_EVENT) {		// Just ignore this error
68
// 			continue;
69
// 		}
70
		message_handle(msg);
71
		free(msg);
72
// 		kolibri_IPC_clear_buff();
1238 vkos 73
	}
74
}
75
 
76
void message_handle(kolibri_IPC_message_t *message){
77
	char *msg = (char *)message+sizeof(kolibri_IPC_message_t);
78
	char cmd = msg[0];
79
	thread_list_t *thread = find_tid(main_group_list, message->tid);
80
	group_list_t *group;
81
	int i;
82
 
83
	if (cmd == KOBRA_CMD_REGISTER && !thread) {
84
		kobra_register(message->tid);
85
	} else if (thread) {
86
		switch (cmd) {
87
			case KOBRA_CMD_JOIN:
88
				if (message->length < 3 || msg[message->length-1] != '\0') {
89
					// Here should be some error handler
90
					return;
91
				}
92
 
93
				if (!(group = find_group(msg+1))){
94
					group = create_group(msg+1);
95
				}
96
				add_to_group(group, message->tid);
97
				break;
98
			case KOBRA_CMD_UNJOIN:
99
				if (message->length < 3 || msg[message->length-1] != '\0') {
100
					// Here should be some error handler
101
					return;
102
				}
103
 
104
				if ((group = find_group(msg+1)) && (thread = find_tid(group, message->tid))) {
105
					remove_from_group(group, thread);
106
				}
107
				break;
108
			case KOBRA_CMD_SEND:
109
				if (message->length < 4) {
110
					// Here should be some error handler
111
					return;
112
				}
113
 
114
				// Check if group name is correct
115
				for (i = 1; i < message->length-1 && msg[i]; ++i);
116
				if (msg[i]) {
117
					// Here should be some error handler
118
					return;
119
				}
120
 
121
				group = find_group(msg+1);
122
				if (!group) {
123
					// Here should be some error handler
124
					return;
125
				}
126
 
127
				send_group_message(group, message->tid, msg+i+1, message->length-i-1);
128
				break;
129
			case KOBRA_CMD_GET_LIST_NAME:
130
				// This is temporary realisation
131
				kolibri_IPC_send(message->tid, KOBRA_MEMAREA_NAME, KOBRA_MEMAREA_NAME_LENGTH);
132
			default:
133
				// Here should be some error handler
134
				return;
135
		}
136
	}
137
}
138
 
139
thread_list_t *find_tid(group_list_t *group, int tid){
140
	thread_list_t *thread_list = group->thread_list, *thread = thread_list;
141
 
142
	if (!thread_list) {
143
		return NULL;
144
	}
145
 
146
	do {
147
		if (thread->tid == tid) {
148
			return thread;
149
		}
150
		thread = thread->next;
151
	} while (thread != thread_list);
152
 
153
	return NULL;
154
}
155
 
156
void kobra_register(int tid){
157
	add_to_group(main_group_list, tid);
158
}
159
 
160
void add_to_group(group_list_t *group, int tid){
161
	thread_list_t *thread_list = group->thread_list, *thread_last;
162
 
163
	if (!thread_list) {
164
		thread_list = group->thread_list = new_thread_list(tid);
165
		thread_list->previos = thread_list->next = thread_list;
166
	} else if (thread_list == (thread_last = thread_list->previos)) {
167
		thread_last = thread_list->next = thread_list->previos = new_thread_list(tid);
168
		thread_last->next = thread_last->previos = thread_list;
169
	} else {
170
		thread_last->next = thread_list->previos = new_thread_list(tid);
171
		thread_last->next->next = thread_list;
172
		thread_last->next->previos = thread_last;
173
	}
174
}
175
 
176
void remove_from_group(group_list_t *group, thread_list_t *thread){
177
	if (thread->next == thread) {
178
		remove_group(group);
179
	} else {
180
		thread->next->previos = thread->previos;
181
		thread->previos->next = thread->next;
182
		if (group->thread_list == thread) {
183
			group->thread_list = thread->next;
184
		}
185
	}
186
 
187
	memarea_free(thread);
188
}
189
 
190
group_list_t *find_group(char *name){
191
	group_list_t *group_list = main_group_list, *group = group_list;
192
 
193
	if (group_list) {
194
		do {
195
			if (!strcmp(group->name, name)) {
196
				return group;
197
			}
198
			group = group->next;
199
		} while (group != group_list);
200
	}
201
 
202
	return NULL;
203
}
204
 
205
void send_group_message(group_list_t *group, int tid, char *message, int length){
206
	thread_list_t *thread_list = group->thread_list, *thread = thread_list;
207
	char *msg = malloc(length+sizeof(int));
208
 
209
	((unsigned long *)msg)[0] = (unsigned long)tid;
210
	memcpy(msg+4, message, length);
211
 
212
	do {
1286 vkos 213
		IPCSend(thread->tid, msg, length+sizeof(int));		// Here may be some errror handler
1238 vkos 214
		thread = thread->next;
215
	} while (thread != thread_list);
216
}
217
 
218
void remove_group(group_list_t *group){
219
	if (group == main_group_list) {
220
		return;
221
	}
222
	group->next->previos = group->previos;
223
	group->previos->next = group->next;
224
	memarea_free(group);
225
}
226
 
227
group_list_t *create_group(char *name){
228
	group_list_t *group_list = main_group_list, *group_last;
229
 
230
	if (!group_list) {
231
		return main_group_list = new_group_list(name);
232
	}
233
 
234
	group_last = group_list->previos;
235
	if (group_list == group_last) {
236
		group_last = group_list->next = group_list->previos = new_group_list(name);
237
		group_last->next = group_last->previos = group_list;
238
	} else {
239
		group_last->next = group_list->previos = new_group_list(name);
240
		group_last->next->next = group_list;
241
		group_last->next->previos = group_last;
242
		group_last = group_last->next;
243
	}
244
 
245
	return group_last;
246
}
247
 
248
group_list_t *new_group_list(char *name){
249
	group_list_t *list = memarea_alloc(sizeof(group_list_t));
250
	if (list) {
251
		list->name = malloc(strlen(name));
252
		strcpy(list->name, name);
253
		list->thread_list = NULL;
254
	}
255
	return list;
256
}
257
 
258
thread_list_t *new_thread_list(int tid){
259
	thread_list_t *list = memarea_alloc(sizeof(thread_list_t));
260
	if (list) {
261
		list->tid = tid;
262
	}
263
	return list;
264
}
265
 
266
asm(".align 16\n.globl end\nend:");