/**
 * Set function table:
 * user declares custom functions and stores them in the table
 * in his high level program, then tells erpc library to use these functions.
 *
 * Erpc is platform agnostic - it knows only to parse JSON and call
 * method with name `fncIdx` with correct parameters. What will this method
 * actually do, it is on user to define.
 */
void erpcAddFunction(char* fncName, void (*f)(int argc, JSMN_PARAMS_t argv))
{
    fncIdx = fnv1a_hash((const unsigned char *)fncName) % FNC_TABLE_SIZE;
    fncTable[fncIdx] = f;
#ifdef ERPC_DEBUG
    printf("Hash %d - %s\n", fncIdx, (const unsigned char*)fncName);
#endif
}
Beispiel #2
0
uint64_t RequestHandler :: compute_hash( HttpMessage& request ){
	if( cache_hash_function != NULL ){
		return cache_hash_function( request );
		}
	else{
		std::string ckey = request.get_method() + ":" + request.get_path();
		return fnv1a_hash( ckey );
		}
	}
/**
 * Parse JSON and call adequate function from lookup table
 */
int erpcCall(char* req, uint8_t size)
{
    int i;
    int r;
    jsmn_parser p;
    jsmntok_t t[16]; /* We expect no more than 128 tokens */
    jsmn_init(&p);

    r = jsmn_parse(&p, req, size, t, sizeof(t)/sizeof(t[0]));
    if (r < 0) {
#ifdef ERPC_DEBUG
        printf("Failed to parse JSON: %d\n", r);
#endif
        return 1;
    }

    /* Assume the top-level element is an object */
    if (r < 1 || t[0].type != JSMN_OBJECT) {
#ifdef ERPC_DEBUG
        printf("Object expected\n");
#endif
        return 1;
    }

    /* Loop over all keys of the root object */
    for (i = 1; i < r; i++) {
        if (jsoneq(req, &t[i], JSONRPC_METHOD_KEY) == 0) {

            int size = t[i+1].end-t[i+1].start;
        
            /* We may use strndup() to fetch string value */
            memcpy(method, req + t[i+1].start, t[i+1].end-t[i+1].start);
            method[size] = '\0';
#ifdef ERPC_DEBUG
            printf("- Method: %s\n", method);
#endif

            fncIdx = fnv1a_hash(method) % FNC_TABLE_SIZE;

#ifdef ERPC_DEBUG
            printf("- Function Table Index: %d\n", fncIdx);
#endif
            i++;
        } else if (jsoneq(req, &t[i], JSONRPC_PARAMS_KEY) == 0) {
            int j;

#ifdef ERPC_DEBUG
            printf("- Params:\n");
#endif
            /** Reset paramNb */
            paramNb = 0;

            if (t[i+1].type != JSMN_ARRAY) {
                continue; /* We expect params to be an array of strings */
            }
            for (j = 0; j < t[i+1].size; j++) {
                jsmntok_t *g = &t[i+j+2];
                int paramSize = g->end - g->start;
                memcpy(params[paramNb], req + g->start, paramSize);
                params[paramNb][paramSize] = '\0';

#ifdef ERPC_DEBUG
                printf("  * %s\n", params[paramNb]);
#endif
                paramNb++;
            }
            i += t[i+1].size + 1;
        } else if (jsoneq(req, &t[i], JSONRPC_REPLY_TO_KEY) == 0) {
            int size = t[i+1].end-t[i+1].start;

            /* We may want to do strtol() here to get numeric value */
            memcpy(replyTo, req + t[i+1].start, size);
            replyTo[size] = '\0';
#ifdef ERPC_DEBUG
            printf("- replyTo: %s\n", replyTo);
#endif
            i++;
        } else {
#ifdef ERPC_DEBUG
            printf("Unexpected key: %.*s\n", t[i].end-t[i].start,
            req + t[i].start);
#endif
        }
    }

    /** Call the function only if the pointer is not pointing on the reset
      * vecotr (0x0) */
    if (fncTable[fncIdx] == 0)
        SendStatus(STATUS_UNRECOGNIZED);
    else
        fncTable[fncIdx](paramNb, params);
    return 0;
}