#include <ubixos/message.h>
#include <lib/kmalloc.h>
#include <lib/string.h>
static int inited = 0;
#define __MESSAGE_CONNECTION_COUNT 4
static const unsigned int connectionCount = __MESSAGE_CONNECTION_COUNT;
static int messageCount = 0;
static connection_t * connections;
static void messageInit()
{
unsigned int i;
if (inited)
return;
connections = (connection_t *) kmalloc(connectionCount * sizeof(connection_t), -1);
for (i = 0; i < connectionCount; i++)
{
kmemset(&connections[i], '\0', sizeof(connection_t));
//waitQueueInit(&connections[i].message_queue, 0);
connections[i].message_queue = new Queue<message_t *>();
//waitQueueInit(&connections[i].old_queue, 0);
connections[i].old_queue = new Queue<message_t *>();
}
inited = 1;
}
int connectionCreate(char * cname, uInt32 * cid, uInt8 flags)
{
unsigned int i;
if (!inited)
messageInit();
for (i = 0; i < connectionCount; i++)
if (connections[i].used == 0)
break;
if (connections[i].used != 0)
return -1;
connections[i].used = 1;
kstrncpy(connections[i].unique_string, cname, 256);
connections[i].owning_pid = _current->id;
*cid = i;
return 0;
}
int connectionOpen(char * cname, uInt32 * cid)
{
unsigned int i;
if (!inited)
messageInit();
for (i = 0; i < connectionCount; i++)
if (connections[i].used == 1)
if (0 == kstrncmp(connections[i].unique_string, cname, 256))
break;
if (connections[i].used == 0)
return -1;
if (0 != kstrncmp(connections[i].unique_string, cname, 256))
return -1;
*cid = i;
return 0;
}
int messageRecv(uInt32 cid, uInt32 * sender, uInt32 * cmd, uInt32 * size, uInt8 * data)
{
message_t * temp = NULL;
//int notUsed;
if (!inited)
return -1;
if (cid >= connectionCount)
return -1;
//if (connections[cid].used == 0);
// return -1;
if (connections[cid].owning_pid != _current->id)
return -1;
do
{
//temp = (message_t *) waitQueueRemove(&connections[cid].message_queue, ¬Used);
temp = connections[cid].message_queue->pop();
if (temp == NULL)
{
setTaskStatus_task(_current, MSGWAIT);
schedule();
}
}
while(temp == NULL);
kmemcpy(data, temp->data, temp->size);
*cmd = temp->cmd;
*size = temp->size;
*sender = temp->send_taskId;
//waitQueueInsert(&connections[cid].old_queue, temp, temp->id);
connections[cid].old_queue->insert(temp->id, temp);
return temp->id;
}
int messageSend(uInt32 cid, uInt32 * cmd, uInt32 * size, uInt8 * data)
{
message_t * temp;
kTask_t * task;
if (!inited)
return -1;
if (cid >= connectionCount)
return -1;
if (connections[cid].used == 0)
return -1;
temp = (message_t *) kmalloc(sizeof(message_t), -1);
temp->cmd = *cmd;
temp->size = *size;
kmemcpy((void *) temp->data, (void *) data, *size);
temp->send_taskId = _current->id;
temp->id = messageCount;
messageCount++;
temp->flags = MSG_SEND;
//waitQueueInsert(&connections[cid].message_queue, (void *) temp, temp->id);
connections[cid].message_queue->insert(temp->id, temp);
task = getTask(connections[cid].owning_pid);
if (task != NULL)
{
if (task->status == MSGWAIT)
setTaskStatus_task(task, READY);
}
while((temp->flags & MSG_REPLY) != MSG_REPLY)
{
setTaskStatus_task(_current, MSGREPLY);
schedule();
}
*cmd = temp->cmd;
*size= temp->size;
kmemcpy((void *) data, (void *) temp->data, *size);
kfree((void *)temp);
return 0;
}
int messageReply(uInt32 cid, uInt32 mid, uInt32 cmd, uInt32 size, uInt8 * data)
{
message_t * temp = NULL;
if (!inited)
return -1;
if (cid >= connectionCount)
return -1;
if (connections[cid].used == 0)
return -1;
//temp = (message_t *) waitQueueFind(&connections[cid].old_queue, mid);
temp = connections[cid].old_queue->find(mid);
if (temp == NULL)
return -1;
temp->flags |= MSG_REPLY;
temp->size = size;
temp->cmd = cmd;
kmemcpy(temp->data, data, cmd);
setTaskStatus(temp->send_taskId, READY);
return 0;
}