00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "vm-buffer.h"
00024 #include "../../common/consts.h"
00025 #include <string.h>
00026 #include <assert.h>
00027
00028 static unsigned char buffer[ASEBA_MAX_PACKET_SIZE];
00029 static unsigned buffer_pos;
00030
00031 static void buffer_add(const uint8* data, uint16 len)
00032 {
00033 uint16 i = 0;
00034 while (i < len)
00035 {
00036
00037
00038
00039
00040
00041
00042 buffer[buffer_pos++] = data[i++];
00043 }
00044 }
00045
00046 static void buffer_add_uint8(uint8 value)
00047 {
00048 buffer_add(&value, 1);
00049 }
00050
00051 static void buffer_add_uint16(uint16 value)
00052 {
00053 buffer_add((unsigned char *) &value, 2);
00054 }
00055
00056 static void buffer_add_sint16(sint16 value)
00057 {
00058 buffer_add((unsigned char *) &value, 2);
00059 }
00060
00061 static void buffer_add_string(const char* s)
00062 {
00063 uint16 len = strlen(s);
00064 buffer_add_uint8((uint8)len);
00065 while (*s)
00066 buffer_add_uint8(*s++);
00067 }
00068
00069
00070
00071 void AsebaSendMessage(AsebaVMState *vm, uint16 type, void *data, uint16 size)
00072 {
00073 uint16 i;
00074
00075 buffer_pos = 0;
00076 buffer_add_uint16(type);
00077 for (i = 0; i < size; i++)
00078 buffer_add_uint8(((unsigned char*)data)[i]);
00079
00080 AsebaSendBuffer(vm, buffer, buffer_pos);
00081 }
00082
00083
00084 void AsebaSendVariables(AsebaVMState *vm, uint16 start, uint16 length)
00085 {
00086 uint16 i;
00087
00088 buffer_pos = 0;
00089 buffer_add_uint16(ASEBA_MESSAGE_VARIABLES);
00090 buffer_add_uint16(start);
00091 for (i = start; i < start + length; i++)
00092 buffer_add_uint16(vm->variables[i]);
00093
00094 AsebaSendBuffer(vm, buffer, buffer_pos);
00095 }
00096
00097 void AsebaSendDescription(AsebaVMState *vm)
00098 {
00099 const AsebaVMDescription *vmDescription = AsebaGetVMDescription(vm);
00100 const AsebaVariableDescription* namedVariables = vmDescription->variables;
00101 const AsebaNativeFunctionDescription* const * nativeFunctionsDescription = AsebaGetNativeFunctionsDescriptions(vm);
00102 const AsebaLocalEventDescription* localEvents = AsebaGetLocalEventsDescriptions(vm);
00103
00104 uint16 i = 0;
00105 buffer_pos = 0;
00106
00107 buffer_add_uint16(ASEBA_MESSAGE_DESCRIPTION);
00108
00109 buffer_add_string(vmDescription->name);
00110
00111 buffer_add_uint16(ASEBA_PROTOCOL_VERSION);
00112
00113 buffer_add_uint16(vm->bytecodeSize);
00114 buffer_add_uint16(vm->stackSize);
00115 buffer_add_uint16(vm->variablesSize);
00116
00117
00118 for (i = 0; namedVariables[i].size; i++)
00119 ;
00120 buffer_add_uint16(i);
00121
00122
00123 for (i = 0; localEvents[i].name; i++)
00124 ;
00125 buffer_add_uint16(i);
00126
00127
00128 for (i = 0; nativeFunctionsDescription[i]; i++)
00129 ;
00130 buffer_add_uint16(i);
00131
00132
00133 AsebaSendBuffer(vm, buffer, buffer_pos);
00134
00135
00136 for (i = 0; namedVariables[i].name; i++)
00137 {
00138 buffer_pos = 0;
00139
00140 buffer_add_uint16(ASEBA_MESSAGE_NAMED_VARIABLE_DESCRIPTION);
00141
00142 buffer_add_uint16(namedVariables[i].size);
00143 buffer_add_string(namedVariables[i].name);
00144
00145
00146 AsebaSendBuffer(vm, buffer, buffer_pos);
00147 }
00148
00149
00150 for (i = 0; localEvents[i].name; i++)
00151 {
00152 buffer_pos = 0;
00153
00154 buffer_add_uint16(ASEBA_MESSAGE_LOCAL_EVENT_DESCRIPTION);
00155
00156 buffer_add_string(localEvents[i].name);
00157 buffer_add_string(localEvents[i].doc);
00158
00159
00160 AsebaSendBuffer(vm, buffer, buffer_pos);
00161 }
00162
00163
00164 for (i = 0; nativeFunctionsDescription[i]; i++)
00165 {
00166 uint16 j;
00167
00168 buffer_pos = 0;
00169
00170 buffer_add_uint16(ASEBA_MESSAGE_NATIVE_FUNCTION_DESCRIPTION);
00171
00172
00173 buffer_add_string(nativeFunctionsDescription[i]->name);
00174 buffer_add_string(nativeFunctionsDescription[i]->doc);
00175 for (j = 0; nativeFunctionsDescription[i]->arguments[j].size; j++)
00176 ;
00177 buffer_add_uint16(j);
00178 for (j = 0; nativeFunctionsDescription[i]->arguments[j].size; j++)
00179 {
00180 buffer_add_sint16(nativeFunctionsDescription[i]->arguments[j].size);
00181 buffer_add_string(nativeFunctionsDescription[i]->arguments[j].name);
00182 }
00183
00184
00185 AsebaSendBuffer(vm, buffer, buffer_pos);
00186 }
00187 }
00188
00189 void AsebaProcessIncomingEvents(AsebaVMState *vm)
00190 {
00191 uint16 source;
00192 const AsebaVMDescription *desc = AsebaGetVMDescription(vm);
00193
00194 uint16 amount = AsebaGetBuffer(vm, buffer, ASEBA_MAX_PACKET_SIZE, &source);
00195
00196 if (amount > 0)
00197 {
00198 uint16 type = ((uint16*)buffer)[0];
00199 uint16* payload = (uint16*)(buffer+2);
00200 uint16 payloadSize = (amount-2)/2;
00201 if (type < 0x8000)
00202 {
00203
00204 if (AsebaMaskIsClear(vm->flags, ASEBA_VM_STEP_BY_STEP_MASK) || AsebaMaskIsClear(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK))
00205 {
00206
00207
00208 uint16 argPos = desc->variables[1].size;
00209 uint16 argsSize = desc->variables[2].size;
00210 uint16 i;
00211 vm->variables[argPos++] = source;
00212 for (i = 0; (i < argsSize) && (i < payloadSize); i++)
00213 vm->variables[argPos + i] = payload[i];
00214 AsebaVMSetupEvent(vm, type);
00215 }
00216 }
00217 else
00218 {
00219
00220 AsebaVMDebugMessage(vm, type, payload, payloadSize);
00221 }
00222 }
00223 }
00224