00001 #include <stdlib.h>
00002 #include <string.h>
00003 #include <sys/msg.h>
00004
00005 #include "hmsg.h"
00006 #include "hprocess.h"
00007 #include "hlog.h"
00008 #include "hstructures.h"
00009 #include "hmqueue.h"
00010
00011
00013 struct hmsg_base {
00014 long type;
00015 struct {
00016 int sender_id;
00017 } mtext;
00018 };
00019
00030
00031
00032 struct hmsg_ctrl {
00033 long type;
00034 struct {
00035 int sender_id;
00036 enum hmsg_command command;
00037 int retval;
00038 } mtext;
00039 };
00040
00042 struct hmsg_ctrlmem {
00043 long type;
00044 struct {
00045 int sender_id;
00046 enum hmsg_command command;
00047 int retval;
00048 int address;
00049 int size;
00050 char data[HMSG_DATA_SIZE];
00051 } mtext;
00052 };
00053
00055 struct hmsg_regproc {
00056 long type;
00057 struct {
00058 int sender_id;
00059 enum hmsg_command command;
00060 int nice;
00061 char bitfilename[HPROCESS_MAX_FILENAME_SIZE];
00062 } mtext;
00063 };
00064
00066 const int mtext_max_size = sizeof(((struct hmsg_ctrlmem*)NULL)->mtext);
00067
00068
00069 static int set_type_(void* msg, int type);
00070 static const int get_mtext_max_size_();
00071 static int get_struct_size_(int type);
00072 static int get_mtext_size_(int type);
00073
00074
00075 static int get_struct_size_(int type)
00076 {
00077 switch (type) {
00078 case HMT_CTRL:
00079 return sizeof(struct hmsg_ctrl);
00080 case HMT_CTRLMEM:
00081 return sizeof(struct hmsg_ctrlmem);
00082 case HMT_REGPROC:
00083 return sizeof(struct hmsg_regproc);
00084 default:
00085 return -1;
00086 }
00087 }
00088
00089
00090 static int get_mtext_size_(int type)
00091 {
00092 switch (type) {
00093 case HMT_CTRL:
00094 return sizeof ((struct hmsg_ctrl*)NULL)->mtext;
00095 case HMT_CTRLMEM:
00096 return sizeof ((struct hmsg_ctrlmem*)NULL)->mtext;
00097 case HMT_REGPROC:
00098 return sizeof ((struct hmsg_regproc*)NULL)->mtext;
00099 default:
00100 return -1;
00101 }
00102 }
00103
00104
00105 static int set_type_(void* msg, int type)
00106 {
00107 if (msg == NULL)
00108 return -1;
00109 else if (type == HMT_CTRL || type == HMT_CTRLMEM || type == HMT_REGPROC) {
00110 ((struct hmsg_base*)msg)->type = type;
00111 return 0;
00112 }
00113
00114 return -2;
00115 }
00116
00117
00118 static const int get_mtext_max_size_()
00119 {
00120 return mtext_max_size;
00121 }
00122
00123
00124 char* hmsg_get_bitfilename(void* msg)
00125 {
00126 if (hmsg_get_type(msg) == HMT_REGPROC)
00127 return (char*)(((struct hmsg_regproc*)msg)->mtext.bitfilename);
00128 else {
00129 hlog_write(HLOG_ERROR, "hmsg_get_bitfilename: Failed to return data. Unknown message type.\n");
00130 return NULL;
00131 }
00132 }
00133
00134
00135 int hmsg_set_bitfilename(void* msg, char* bitfilename)
00136 {
00137 if (hmsg_get_type(msg) == HMT_REGPROC) {
00138 strncpy(hmsg_get_bitfilename(msg), bitfilename, HPROCESS_MAX_FILENAME_SIZE);
00139 return 0;
00140 } else {
00141 hlog_write(HLOG_ERROR, "hmsg_set_bitfilename: Failed to set data. Unknown message type.\n");
00142 return -1;
00143 }
00144 }
00145
00146
00147 int hmsg_get_nice(void* msg)
00148 {
00149 if (hmsg_get_type(msg) == HMT_REGPROC)
00150 return ((struct hmsg_regproc*)msg)->mtext.nice;
00151 else
00152 return -1;
00153 }
00154
00155
00156 int hmsg_set_nice(void* msg, int nice)
00157 {
00158 if (hmsg_get_type(msg) == HMT_REGPROC) {
00159 ((struct hmsg_regproc*)msg)->mtext.nice = nice;
00160 return 0;
00161 } else
00162 return -1;
00163 }
00164
00165
00166 int hmsg_set_sender(void* msg, int id)
00167 {
00168 if (msg == NULL)
00169 return -1;
00170
00171 ((struct hmsg_base*)msg)->mtext.sender_id = id;
00172
00173 return 0;
00174 }
00175
00176
00177 int hmsg_get_sender(void* msg)
00178 {
00179 if (msg == NULL)
00180 return -1;
00181
00182 return ((struct hmsg_base*)msg)->mtext.sender_id;
00183 }
00184
00185
00186 int hmsg_get_type(void* msg)
00187 {
00188 if (msg == NULL)
00189 return -1;
00190
00191 return ((struct hmsg_base*)msg)->type;
00192 }
00193
00194
00195 int hmsg_set_return(void* msg, enum hmsg_return retval)
00196 {
00197 if (hmsg_get_type(msg) == HMT_CTRL || hmsg_get_type(msg) == HMT_CTRLMEM) {
00198 ((struct hmsg_ctrl*)msg)->mtext.retval = retval;
00199 return 0;
00200 } else
00201 return -1;
00202 }
00203
00204
00205 enum hmsg_return hmsg_get_return(void* msg)
00206 {
00207 if (hmsg_get_type(msg) == HMT_CTRL || hmsg_get_type(msg) == HMT_CTRLMEM)
00208 return ((struct hmsg_ctrl*)msg)->mtext.retval;
00209 else
00210 return -1;
00211 }
00212
00213
00214 int hmsg_get_size(void* msg)
00215 {
00216 if (hmsg_get_type(msg) != HMT_CTRLMEM)
00217 return -1;
00218
00219 return ((struct hmsg_ctrlmem*)msg)->mtext.size;
00220 }
00221
00222 int hmsg_set_size(void* msg, int size)
00223 {
00224 if (hmsg_get_type(msg) != HMT_CTRLMEM)
00225 return -1;
00226
00227 ((struct hmsg_ctrlmem*)msg)->mtext.size = size;
00228
00229 return 0;
00230 }
00231
00232 char* hmsg_get_data(void* msg)
00233 {
00234 switch (hmsg_get_type(msg)) {
00235 case HMT_CTRLMEM:
00236 return (char*)(((struct hmsg_ctrlmem*)msg)->mtext.data);
00237 default:
00238 hlog_write(HLOG_ERROR, "hmsg_get_data: Failed to return data. Unknown message (type=");
00239 hlog_write_integer(hmsg_get_type(msg));
00240 hlog_write_text(").\n");
00241 return NULL;
00242 }
00243 }
00244
00245
00246 int hmsg_set_data(void* msg, char* data)
00247 {
00248 if (hmsg_get_type(msg) == HMT_CTRLMEM) {
00249 strncpy(hmsg_get_data(msg), data, HMSG_DATA_SIZE);
00250 return 0;
00251 } else
00252 return -1;
00253 }
00254
00255 int hmsg_set_address(void* msg, int address)
00256 {
00257 if (hmsg_get_type(msg) == HMT_CTRLMEM)
00258 ((struct hmsg_ctrlmem*)msg)->mtext.address = address;
00259 else {
00260 hlog_write(HLOG_ERROR, "hmsg_set_address: Failed to set address. Unknown message type.\n");
00261 return -1;
00262 }
00263
00264 return 0;
00265 }
00266
00267
00268 int hmsg_get_address(void* msg)
00269 {
00270 if (hmsg_get_type(msg) == HMT_CTRLMEM)
00271 return ((struct hmsg_ctrlmem*)msg)->mtext.address;
00272 else {
00273 hlog_write(HLOG_ERROR, "hmsg_set_address: Failed to set address. Unknown message type.\n");
00274 return -1;
00275 }
00276 }
00277
00278 int hmsg_send(void* msg, struct hmqueue* msq)
00279 {
00280 int msqid = hmqueue_get_id(msq);
00281 hlog_write(HLOG_DEBUG, "hmsg_send: Adding message to message queue. msqid=");
00282 hlog_write_integer(msqid);
00283 hlog_write_text(".\n");
00284
00285 switch( hmsg_get_type(msg) ) {
00286 case HMT_CTRL:
00287 return msgsnd(msqid, (struct hmsg_ctrl*)msg, get_mtext_size_(HMT_CTRL), 0);
00288 case HMT_CTRLMEM:
00289 return msgsnd(msqid, (struct hmsg_ctrlmem*)msg, get_mtext_size_(HMT_CTRLMEM), 0);
00290 case HMT_REGPROC:
00291 return msgsnd(msqid, (struct hmsg_regproc*)msg, get_mtext_size_(HMT_REGPROC), 0);
00292 default:
00293 hlog_write(HLOG_ERROR, "hmsg_send: Failed to send message. Unknown type.\n");
00294 return -2;
00295 }
00296 }
00297
00298
00299 enum hmsg_command hmsg_get_command(void* msg)
00300 {
00301 switch( hmsg_get_type(msg) ) {
00302 case HMT_CTRL:
00303 return ((struct hmsg_ctrl*)msg)->mtext.command;
00304 case HMT_CTRLMEM:
00305 return ((struct hmsg_ctrlmem*)msg)->mtext.command;
00306 case HMT_REGPROC:
00307 return ((struct hmsg_regproc*)msg)->mtext.command;
00308 default:
00309 return -1;
00310 }
00311 }
00312
00313
00314 int hmsg_set_command(void* msg, enum hmsg_command command)
00315 {
00316 switch( hmsg_get_type(msg) ) {
00317 case HMT_CTRL:
00318 ((struct hmsg_ctrl*)msg)->mtext.command = command;
00319 break;
00320 case HMT_CTRLMEM:
00321 ((struct hmsg_ctrlmem*)msg)->mtext.command = command;
00322 break;
00323 case HMT_REGPROC:
00324 ((struct hmsg_regproc*)msg)->mtext.command = command;
00325 break;
00326 default:
00327 return -1;
00328 }
00329
00330 return 0;
00331 }
00332
00333
00334 void* hmsg_create(int type)
00335 {
00336
00337
00338 if (type == HMT_CTRL) {
00339 struct hmsg_ctrl* ctrl_msg;
00340 ctrl_msg = (struct hmsg_ctrl*)calloc(1, sizeof(struct hmsg_ctrl));
00341 if (set_type_(ctrl_msg, HMT_CTRL) < 0) {
00342 free(ctrl_msg);
00343 return NULL;
00344 }
00345 hmsg_set_command(ctrl_msg, -1);
00346 hmsg_set_size(ctrl_msg, -1);
00347 hmsg_set_return(ctrl_msg, -1);
00348 return ctrl_msg;
00349 } else if (type == HMT_CTRLMEM) {
00350 struct hmsg_ctrlmem* ctrlmem_msg;
00351 ctrlmem_msg = (struct hmsg_ctrlmem*)calloc(1, sizeof(struct hmsg_ctrlmem));
00352 if (set_type_(ctrlmem_msg, HMT_CTRLMEM) < 0) {
00353 free(ctrlmem_msg);
00354 return NULL;
00355 }
00356 hmsg_set_command(ctrlmem_msg, -1);
00357 hmsg_set_address(ctrlmem_msg, -1);
00358 hmsg_set_return(ctrlmem_msg, -1);
00359 hmsg_set_size(ctrlmem_msg, -1);
00360 hmsg_set_data(ctrlmem_msg, "");
00361 return ctrlmem_msg;
00362 } else if (type == HMT_REGPROC) {
00363 struct hmsg_regproc* regproc_msg;
00364 regproc_msg = (struct hmsg_regproc*)calloc(1, sizeof(struct hmsg_regproc));
00365 if (set_type_(regproc_msg, HMT_REGPROC) < 0) {
00366 free(regproc_msg);
00367 return NULL;
00368 }
00369 hmsg_set_nice(regproc_msg, -1);
00370
00371 hmsg_set_command(regproc_msg, HMC_REGPROC);
00372 hmsg_set_bitfilename(regproc_msg, "");
00373 return regproc_msg;
00374 } else {
00375 hlog_write(HLOG_ERROR, "hmsg_create: Failed to create message. Unknown type.\n");
00376 return NULL;
00377 }
00378 }
00379
00380
00381 int hmsg_remove(void* msg)
00382 {
00383 if (msg == NULL)
00384 return -1;
00385
00386 free(msg);
00387
00388 return 0;
00389 }
00390
00391
00392 void* hmsg_receive(struct hmqueue* msq)
00393 {
00394 void* msg = NULL;
00395 int msqid = hmqueue_get_id(msq);
00396
00397
00398 msg = calloc(1, get_mtext_max_size_() + sizeof(long));
00399 msgrcv(msqid, msg, get_mtext_max_size_(), 0, 0);
00400
00401 msg = realloc(msg, get_struct_size_( hmsg_get_type(msg) ));
00402
00403 return msg;
00404 }
00405
00406