Esempio n. 1
0
/**
 * "send" method handler
 */
STATIC XRpcElement* GWENG_MidpSend(void* ctx, const XRpcContainer* param)
{
    /* decode parameters */
    const XRpcIntElement* sidParam =
        XRPC_GetIntElementByName(param, 
        ECMTGW_SEI_SEND_SID_PARAM);

    const XRpcIntElement* cidParam =
        XRPC_GetIntElementByName(param, 
        ECMTGW_SEI_SEND_CID_PARAM);

    const XRpcBinaryElement* dataParam =
        XRPC_GetBinaryElementByName(param, 
        ECMTGW_SEI_SEND_DATA_PARAM);

    if (sidParam && cidParam && dataParam) {
        MidpSession* midp;
        EcmtGateway* gw = ctx;
        size_t size = XRPC_GetBinaryDataSize(dataParam);
        I32u cid = XRPC_GetInt(cidParam);
        const XRpcByte* data = XRPC_GetBinaryData(dataParam);

        MidpSessionKey key;
        key.xrpcSid = XRPC_GetInt(sidParam);
        key.xrpcSession = XRPC_GetCurrentSession(gw->xrpc);

        TRACE4("GW: MidpSend(%08x.%08x.%u, %d bytes)\n",
            key.xrpcSession, key.xrpcSid, cid, size);
        DEBUG_ONLY(PRINT_Dump(DEBUG_Trace,data,size,0));

        MUTEX_Lock(&gw->mutex);
        midp = HASH_Get(&gw->midpSessionMap,&key);
        if (midp) {
            MidpConnection* conn = HASH_Get(&midp->connMap,(HashKey)cid);
            if (conn) {
                char h[ECMT_MIDP_DEBUG_SEND_DATA_OFFSET];
                I32u seq = conn->outCount++;
                GWENG_MidpFillHeader(h,midp->sid,ECMT_MIDP_DEBUG_OPCODE_SEND);
                *((I32u*)(h+ECMT_MIDP_DEBUG_SEND_CID_OFFSET)) = htonl(cid);
                *((I32u*)(h+ECMT_MIDP_DEBUG_SEND_SEQ_OFFSET)) = htonl(seq);
                GWENG_QueueAdd2(gw->handsetQueue, KECMT_MIDP_DEBUG_PLUGIN_UID,
                    h, ECMT_MIDP_DEBUG_SEND_DATA_OFFSET, data, size);
            } else {
                TRACE1("GW: invalid conn id %u\n",cid);
                GWENG_MidpResetConn(gw, midp, cid, False, True);
            }
        } else {
            TRACE2("GW: unexpected MIDP send (%08x.%08x)\n",
                key.xrpcSession, key.xrpcSid);
        }
        MUTEX_Unlock(&gw->mutex);
    }

    return NULL;
}
Esempio n. 2
0
/**
 * ECMT message filter
 */
Bool GWENG_MidpFilter(EcmtReader* reader, int uid, 
                      const void* data, int datalen)
{
    if (uid == KECMT_MIDP_DEBUG_GATEWAY_UID) {
        ASSERT(datalen >= ECMT_MIDP_DEBUG_HEADER_SIZE);
        if (datalen >= ECMT_MIDP_DEBUG_HEADER_SIZE) {
            MidpSession* midp;
            EcmtGateway* gw = reader->gw;
            I32u sid;
            I8u opcode = GWENG_MidpParseHeader(data,&sid);

            MUTEX_Lock(&gw->mutex);
            midp = HASH_Get(&gw->ecmtSessionMap,(HashKey)sid);
            if (midp) {
                GWENG_MidpHandleEcmtPacket(gw, midp, data, datalen);
            } else {
                TRACE1("GW: invalid SID 0x%08x\n",sid);
            }
            MUTEX_Unlock(&gw->mutex);
        }
        return False;
    } else {
        return True;
    }
}
Esempio n. 3
0
/**
 * "connect" method handler
 */
STATIC XRpcElement* GWENG_MidpConnect(void* ctx, const XRpcContainer* param)
{
    /* decode parameters */
    const XRpcIntElement* sidParam =
        XRPC_GetIntElementByName(param, 
        ECMTGW_SEI_CONNECT_SID_PARAM);

    const XRpcIntElement* cidParam =
        XRPC_GetIntElementByName(param, 
        ECMTGW_SEI_CONNECT_CID_PARAM);

    const XRpcShortElement* portParam =
        XRPC_GetShortElementByName(param, 
        ECMTGW_SEI_CONNECT_PORT_PARAM);

    if (sidParam && cidParam && portParam) {
        MidpSession* midp;
        EcmtGateway* gw = ctx;
        I32u cid = XRPC_GetInt(cidParam);
        Port port = XRPC_GetShort(portParam);

        MidpSessionKey key;
        key.xrpcSid = XRPC_GetInt(sidParam);
        key.xrpcSession = XRPC_GetCurrentSession(gw->xrpc);

        TRACE4("GW: MidpConnect(%08x.%08x.%u, port %hu)\n",
            key.xrpcSession, key.xrpcSid, cid, port);

        MUTEX_Lock(&gw->mutex);
        midp = HASH_Get(&gw->midpSessionMap,&key);
        if (midp) {
            MidpConnection* conn = MEM_New(MidpConnection);
            if (conn) {
                memset(conn, 0, sizeof(*conn));
                conn->connId = cid;
                if (HASH_Put(&midp->connMap, (HashKey)cid, conn)) {
                    char pkt[ECMT_MIDP_DEBUG_CONNECT_SIZE];
                    GWENG_MidpFillHeader(pkt,midp->sid,ECMT_MIDP_DEBUG_OPCODE_CONNECT);
                    *((I32u*)(pkt+ECMT_MIDP_DEBUG_CONNECT_CID_OFFSET)) = htonl(cid);
                    *((I16u*)(pkt+ECMT_MIDP_DEBUG_CONNECT_PORT_OFFSET)) = htons(port);
                    GWENG_QueueAdd(gw->handsetQueue, KECMT_MIDP_DEBUG_PLUGIN_UID, pkt,
                        ECMT_MIDP_DEBUG_CONNECT_SIZE);
                    MUTEX_Unlock(&gw->mutex);
                    return NULL;
                }
                MEM_Free(conn);
            }
            GWENG_MidpResetConn(gw, midp, cid, False, True);
        } else {
            TRACE3("GW: unexpected MIDP connect (%08x.%08x.%u)\n",
                key.xrpcSession, key.xrpcSid, cid);
        }
        MUTEX_Unlock(&gw->mutex);
    }

    return NULL;
}
Esempio n. 4
0
/**
 * @brief Calls the registered lua onload callback function.
 * @param[in] L The lua state for calling lua.
 * @param[in] key script The name of the .ufo file holding the lua script.
 * @note The signature of the lua function is without any paramters: function ().
 * @note If the signature changes, this function should change too.
 */
void CL_ExecuteCallback (lua_State *L, const char* key) {
	/* look up the handler */
	void *value = HASH_Get(cl_callback, key, strlen (key));
	if (value) {
		int regvalue = * ((int*)value);
		lua_rawgeti (L, LUA_REGISTRYINDEX, regvalue);
		if (lua_pcall (L, 0, 0, 0) != 0) {
			Com_Printf ("lua error: %s\n", lua_tostring(cl_luastate, -1));
		};
	}
}
Esempio n. 5
0
/**
 * @brief Finds the lua based method on this node or its super.
 * @param[in] node The node to examine.
 * @param[in] name The name of the method to find
 * @param[out] fcn A reference to a LUA_METHOD value to the corresponding lua based function or to LUA_NOREF if
 * the method is not found
 * @return True if the method is found, false otherwise.
 * @note This method will first search for instance methods, then it will check for behaviour methods.
 */
bool UI_GetNodeMethod (const uiNode_t* node, const char* name, LUA_METHOD &fcn) {
	fcn = LUA_NOREF;
	// search the instance methods
	for(const uiNode_t* ref=node;ref;ref = ref->super) {
		if (ref->nodeMethods) {
            void* val=HASH_Get(ref->nodeMethods, name, strlen(name));
			if (val != nullptr) {
				fcn = *((LUA_METHOD *)val);
				return true;
			}
		}
	}
	// no instance method found, now scan for behaviour method
	return UI_GetBehaviourMethod(node->behaviour, name, fcn);
}
Esempio n. 6
0
/**
 * "close" method handler
 */
STATIC XRpcElement* GWENG_MidpClose(void* ctx, const XRpcContainer* param)
{
    /* decode parameters */
    const XRpcIntElement* sidParam =
        XRPC_GetIntElementByName(param, 
        ECMTGW_SEI_SEND_SID_PARAM);

    if (sidParam) {
        EcmtGateway* gw = ctx;
        MidpSession* midp;

        MidpSessionKey key;
        key.xrpcSid = XRPC_GetInt(sidParam);
        key.xrpcSession = XRPC_GetCurrentSession(gw->xrpc);
        
        MUTEX_Lock(&gw->mutex);
        TRACE2("GW: MidpClose(%08x.%08x)\n",
            key.xrpcSession, key.xrpcSid);

        midp = HASH_Get(&gw->midpSessionMap,&key);
        if (midp) {
            char p[ECMT_MIDP_DEBUG_CLOSE_SIZE];
            GWENG_MidpFillHeader(p, midp->sid, ECMT_MIDP_DEBUG_OPCODE_CLOSE);
            GWENG_QueueAdd(gw->handsetQueue,KECMT_MIDP_DEBUG_PLUGIN_UID,p,
                ECMT_MIDP_DEBUG_CLOSE_SIZE);

            TRACE1("GW: closing session 0x%08lx (via XRPC)\n",midp->sid);
            GWENG_MidpFree(gw, midp);
        } else {
            TRACE("GW: XRPC close for non-existent session\n");
        }
        MUTEX_Unlock(&gw->mutex);

    } else {
        TRACE("GW: close without cid!\n");
    }

    return NULL;
}
Esempio n. 7
0
/**
 * "reset" method handler
 */
STATIC XRpcElement* GWENG_MidpReset(void* ctx, const XRpcContainer* param)
{
    /* decode parameters */
    const XRpcIntElement* sidParam =
        XRPC_GetIntElementByName(param, 
        ECMTGW_SEI_CONNECT_SID_PARAM);

    const XRpcIntElement* cidParam =
        XRPC_GetIntElementByName(param, 
        ECMTGW_SEI_CONNECT_CID_PARAM);

    if (sidParam && cidParam) {
        MidpSession* midp;
        EcmtGateway* gw = ctx;
        I32u cid = XRPC_GetInt(cidParam);

        MidpSessionKey key;
        key.xrpcSid = XRPC_GetInt(sidParam);
        key.xrpcSession = XRPC_GetCurrentSession(gw->xrpc);

        TRACE3("GW: MidpReset(%08x.%08x.%u)\n",
            key.xrpcSession, key.xrpcSid, cid);

        MUTEX_Lock(&gw->mutex);
        midp = HASH_Get(&gw->midpSessionMap,&key);
        if (midp) {
            GWENG_MidpResetConn(gw, midp, cid, True, False);
        } else {
            TRACE3("GW: unexpected MIDP reset (%08x.%08x.%u)\n",
                key.xrpcSession, key.xrpcSid, cid);
        }
        MUTEX_Unlock(&gw->mutex);
    }

    return NULL;
}
Esempio n. 8
0
/**
 * @brief Unit test function.
 */
bool HASH_test () {
	// return value
	bool result = true;

	/* test 1: create the hash table, delete the hash table */
	hashTable_s* table = HASH_NewTable(true, true, true);
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;

	/* test 2: create the hash table, insert 3 values, delete the hash table */
	table = HASH_NewTable(true, true, true);
	HASH_Insert (table, "AAA", 4, "AAA", 4);
	HASH_Insert (table, "BBB", 4, "BBB", 4);
	HASH_Insert (table, "CCC", 4, "CCC", 4);
	if (HASH_Count(table) != 3) return false;
	HASH_Clear (table);
	if (HASH_Count(table) != 0) return false;
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;

	/* test 3: create the hash table, insert/remove 3 values, delete the hash table */
	table = HASH_NewTable(true, true, true);
	HASH_Insert (table, "AAA", 4, "AAA", 4);
	HASH_Remove (table, "AAA", 4);
	HASH_Insert (table, "BBB", 4, "BBB", 4);
	HASH_Remove (table, "BBB", 4);
	HASH_Insert (table, "CCC", 4, "CCC", 4);
	HASH_Remove (table, "CCC", 4);
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;

	/* test 4: create the hash table, insert/count/search/delete 3 values, delete the hash table */
	table = HASH_NewTable(true, true, true);
	HASH_Insert (table, "AAA", 4, "AAA", 4);
	HASH_Insert (table, "BBB", 4, "BBB", 4);
	HASH_Insert (table, "CCC", 4, "CCC", 4);
	/* check count items */
	if (HASH_Count(table) != 3) return false;
    char* aaa = (char*)HASH_Get(table, "AAA", 4);
    if (strncmp (aaa, "AAA", 4) != 0) return false;
    char* bbb = (char*)HASH_Get(table, "BBB", 4);
    if (strncmp (bbb, "BBB", 4) != 0) return false;
    char* ccc = (char*)HASH_Get(table, "CCC", 4);
    if (strncmp (ccc, "CCC", 4) != 0) return false;
	HASH_Remove (table, "AAA", 4);
	HASH_Remove (table, "BBB", 4);
	HASH_Remove (table, "CCC", 4);
	if (HASH_Count(table) != 0) return false;
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;

	/* test 5: hash function test */
	const char AZ[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	char buffer[26];
	/* compute the averag of the hash index of 400 random keys */
    int total = 0;
    srand(time(NULL));
    for(int i=0; i < 4000; i++) {
		/* create random key of random length between 4..23 charachters */
		int len = 4 + (rand() % 20);
		memset (buffer, 0, sizeof(buffer));
		for (int j=0; j < len; j++) {
			int v = rand() % sizeof(AZ);
			buffer[j]=AZ[v];
		}
		/* compute the hash index */
		int idx = default_hash (buffer, len);
		/* sum index */
		total += idx;
    }
    /* now compute the average of the indices */
    int avg = (total / 4000);
	/* the average idx should be somewhere halfway, allow a %10 error margin */
	int idx_low = (HASH_TABLE_SIZE/2) - (HASH_TABLE_SIZE/10);
	int idx_high = (HASH_TABLE_SIZE/2) + (HASH_TABLE_SIZE/10);
	if ( !((idx_low <= avg) && (idx_high >= avg)) ) return false;

	/* test 6: hash table without ownership test */
	table = HASH_NewTable(true, false, true);
	char item1[] = "AAA";
	char item2[] = "BBB";
	char item3[] = "CCC";
	HASH_Insert (table, item1, 4, item1, 4);
	HASH_Insert (table, item2, 4, item2, 4);
	HASH_Insert (table, item3, 4, item3, 4);
	/* check if we get the correct value pointers */
	aaa = (char*)HASH_Get(table, "AAA", 4);
	if (aaa != item1) return false;
	bbb = (char*)HASH_Get(table, "BBB", 4);
	if (bbb != item2) return false;
	ccc = (char*)HASH_Get(table, "CCC", 4);
	if (ccc != item3) return false;
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;


	/* end of unit test, everything OK */
	return true;
}
Esempio n. 9
0
/**
 * Handles ECMT packet coming from MIDP debug plugin
 */
STATIC void GWENG_MidpHandleEcmtPacket(EcmtGateway* gw,
                                       MidpSession* midp, 
                                       const I8u* pkt, 
                                       int pktlen)
{
    I8u opcode = pkt[ECMT_MIDP_DEBUG_HEADER_OPCODE_OFFSET];
    switch (opcode)
    {
    case ECMT_MIDP_DEBUG_OPCODE_SEND:
        ASSERT(pktlen >= ECMT_MIDP_DEBUG_SEND_MIN_SIZE);
        if (pktlen >= ECMT_MIDP_DEBUG_SEND_MIN_SIZE) {
            I32u cid = htonl(*((I32u*)(pkt+ECMT_MIDP_DEBUG_SEND_CID_OFFSET)));
            I32u seq = htonl(*((I32u*)(pkt+ECMT_MIDP_DEBUG_SEND_SEQ_OFFSET)));
            MidpConnection* conn = HASH_Get(&midp->connMap,(HashKey)cid);
            if (conn) {
                if (conn->inCount == seq) {
                    XRpcData data;
                    XRpcContainer* params;
                    conn->inCount++; /* increment sequence number */
                    data.ptr = (I8u*)pkt + ECMT_MIDP_DEBUG_SEND_DATA_OFFSET;
                    data.size = pktlen - ECMT_MIDP_DEBUG_SEND_DATA_OFFSET;
                    TRACE4("GW: MidpReceive(%08x.%08x.%u, %d bytes)\n",
                        midp->key.xrpcSession, midp->key.xrpcSid, cid,
                        data.size);
                    DEBUG_ONLY(PRINT_Dump(DEBUG_Trace,data.ptr,data.size,0));
                    params = GWENG_CreateXRpcParams(midp,
                        ECMTGW_SEI_SEND_SID_PARAM, 
                        ECMTGW_SEI_SEND_CID_PARAM, cid);
                    if (params) {
                        XRpcElement* dataElem = _XRPC_CreateBinaryElement(
                            data.ptr, data.size);
                        if (dataElem) {
                            if (XRPC_SetElementName(dataElem,
                                ECMTGW_SEI_SEND_DATA_PARAM) &&
                                XRPC_AddElement(params, dataElem)) {
                                /* submit the call */
                                GWENG_SubmitAsyncCall(midp, 
                                    ECMTGW_SEI_SEND_METHOD, 
                                    params);
                                break;
                            } else {
                                XRPC_FreeElement(dataElem);
                            }
                        }
                        XRPC_FreeContainer(params);
                    }
                    /* Terminate connection? That would probably fail too */
                } else {
                    TRACE2("GW: SEQ mismatch (expected %u, found %u)\n",
                        conn->inCount, seq);
                    GWENG_MidpResetConn(gw, midp, cid, True, True);
                }
            } else {
                TRACE1("GW: invalid conn id %u from Ecmt\n",cid);
                GWENG_MidpResetConn(gw, midp, cid, True, False);
            }
        }
        break;

    case ECMT_MIDP_DEBUG_OPCODE_CLOSE:
        ASSERT(pktlen == ECMT_MIDP_DEBUG_CLOSE_SIZE);
        TRACE1("GW: closing session 0x%08lx (via ECMT)\n",midp->sid);
        GWENG_SubmitAsyncCall(midp,
            ECMTGW_SEI_CLOSE_METHOD,
            GWENG_CreateXRpcParams(midp,
                ECMTGW_SEI_CLOSE_SID_PARAM, 
                NULL, 0));
        break;

    case ECMT_MIDP_DEBUG_OPCODE_RESET:
        ASSERT(pktlen == ECMT_MIDP_DEBUG_RESET_SIZE);
        if (pktlen == ECMT_MIDP_DEBUG_RESET_SIZE) {
            I32u cid = htonl(*((I32u*)(pkt+ECMT_MIDP_DEBUG_RESET_CID_OFFSET)));
            GWENG_SubmitAsyncCall(midp,
                ECMTGW_SEI_RESET_METHOD,
                GWENG_CreateXRpcParams(midp,
                    ECMTGW_SEI_RESET_SID_PARAM, 
                    ECMTGW_SEI_RESET_CID_PARAM, cid));
        }
        break;

    default:
        ASSMSG1("GW: unexpected opcode %u",opcode);
        break;
    }
}