FreeCalypso > hg > fc-tourmaline
view src/g23m-fad/app/app_gdd.c @ 78:c632896652ba
mfw/ti1_key.c: properly initialize notified_keys array
The code in this ti1_key.c layer needs to call kpd_subscribe() and
kpd_define_key_notification() functions in order to register with the
KPD driver. The original code passed KPD_NB_PHYSICAL_KEYS in
nb_notified_keys - this constant is defined to 24 in kpd_cfg.h on all
platforms of interest to us - but it only filled the first 23 slots
in the notified_keys array, resulting in stack garbage being passed
to KPD API functions. The fix consists of initializing the last
missed array slot to KPD_KEY_RECORD, the key ID for the right side
button on the D-Sample handset.
On our current hw targets this "Record" button exists as the EXTRA
button on our Luna keypad board and as the camera button on the
Pirelli DP-L10. There is no support whatsoever for this button
in current BMI+MFW, we have no plans of doing anything with Pirelli's
camera button even if we do get our UI fw running on that phone,
and the Mother's dream of building our own FreeCalypso handset with
the same button arrangement as D-Sample (including the right side
button) is currently very nebulous - but let us nonetheless handle
the full set of buttons on the KPD to MFW interface, and let upper
layers weed out unsupported buttons.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Oct 2020 23:41:01 +0000 |
parents | fa8dc04885d8 |
children |
line wrap: on
line source
/* +------------------------------------------------------------------------------ | File: app_gdd.c +------------------------------------------------------------------------------ | Copyright 2004 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : Test functions for testing the GDD interface -- command parser. +----------------------------------------------------------------------------- */ #define APP_GDD_C /*==== INCLUDES =============================================================*/ #include "app_util.h" #include <string.h> /* String functions, e. g. strncpy(). */ #include <ctype.h> #include <stdlib.h> #ifndef _SIMULATION_ #endif /* _SIMULATION_ */ #include "vsi.h" /* A lot of macros. */ #ifndef _SIMULATION_ #include "custom.h" #include "gsm.h" /* A lot of macros. */ #include "tools.h" /* Common tools. */ #endif /* _SIMULATION_ */ #include "../gdd_dio/gdd.h" #include "../gdd_dio/gdd_dio.h" #include "../gdd_dio/dio_il_psi_stub.h" /* for DIO buffer manipulation functions */ /*==== Local defines =========================================================*/ /* Some bogus con handle */ #define TEST_CON_HANDLE 1 /* Max number of test connections required */ #define TEST_MAX_CON 4 /* * Command handler */ /* The base GDD interface functions */ static char *app_gdd_init(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_deinit(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_connect(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_disconnect(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_get_send_buffer(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_send_data(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_receive_data(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_sig_ready_rcv(app_cmd_entry_t *, int, char * [], core_func_t) ; /* More complex test functions encapsulated in functions */ static char *app_gdd_init_test_parms(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_deinit_test_parms(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_connect_test_parms(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_disconnect_test_parms(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_get_send_buffer_test_parms(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_send_data_test_parms(app_cmd_entry_t *, int, char * [], core_func_t) ; static char *app_gdd_immediate_disconnect(app_cmd_entry_t *, int, char * [], core_func_t) ; #ifdef WIN32 /* This function uses psi stub functions which are only available in simulation testing */ static char *app_gdd_test_sig_sbuf_avail(app_cmd_entry_t *, int, char * [], core_func_t) ; #endif /* WIN32 */ /*extern char *app_gdd_sys_test(app_cmd_entry_t *, int, char * [], core_func_t) ;*/ static char *app_gdd_test_helper_functions(app_cmd_entry_t *, int, char * [], core_func_t) ; /* * Core functions (to be called by the command handler, if applicable) */ /* -- No core functions required for now */ /* Command handler table. */ static app_cmd_entry_t app_gdd_cmd_table[] = { /* Commands that trigger the basic GDD API functions */ { "gdd_init", (cmd_handler_t)app_gdd_init, (core_func_t)0, "[BAT|APP] {HowManyCon} [NO|YES]" }, { "gdd_deinit", (cmd_handler_t)app_gdd_deinit, (core_func_t)0, "[BAT|APP]" }, { "gdd_connect", (cmd_handler_t)app_gdd_connect, (core_func_t)0, "[BAT|APP]" }, { "gdd_disconnect", (cmd_handler_t)app_gdd_disconnect, (core_func_t)0, "{ConNum}" }, { "gdd_get_send_buffer", (cmd_handler_t)app_gdd_get_send_buffer, (core_func_t)0, "{ConNum} {NumBytes}" }, { "gdd_test_send_data", (cmd_handler_t)app_gdd_send_data, (core_func_t)0, "{ConNum} {NumBytes}" }, { "gdd_test_receive_data",(cmd_handler_t)app_gdd_receive_data, (core_func_t)0, "{ConNum} {NumBytes}" }, { "gdd_sig_ready_rcv", (cmd_handler_t)app_gdd_sig_ready_rcv, (core_func_t)0, "{ConNum}" }, /* Commands that test the input parameters of the API functions. These tests are to make sure that the API can handler crappy user input/parameter values. */ { "gdd_init_test_parms", (cmd_handler_t)app_gdd_init_test_parms, (core_func_t)0, "" }, { "gdd_deinit_test_parms", (cmd_handler_t)app_gdd_deinit_test_parms, (core_func_t)0, "" }, { "gdd_connect_test_parms", (cmd_handler_t)app_gdd_connect_test_parms, (core_func_t)0, "" }, { "gdd_disconnect_test_parms", (cmd_handler_t)app_gdd_disconnect_test_parms, (core_func_t)0, "" }, { "gdd_get_send_buffer_test_parms", (cmd_handler_t)app_gdd_get_send_buffer_test_parms, (core_func_t)0, "" }, { "gdd_send_data_test_parms", (cmd_handler_t)app_gdd_send_data_test_parms, (core_func_t)0, "" }, /* Test miscellaneous API function / combinations / special cases */ { "gdd_test_immediate_disconnect", (cmd_handler_t)app_gdd_immediate_disconnect, (core_func_t)0, "" }, #ifdef WIN32 { "gdd_test_sig_sbuf_avail", (cmd_handler_t)app_gdd_test_sig_sbuf_avail, (core_func_t)0, "" }, #endif /* WIN32 */ { "gdd_helper_test", (cmd_handler_t)app_gdd_test_helper_functions, (core_func_t)0, "" }, /* { "gdd_sys_test", app_gdd_sys_test, 0, "" }, */ { 0, 0, 0, 0}, /* Terminate table */ } ; /*==== Local data ============================================================*/ #define GDD_MTU_SIZE 1500 static const T_GDD_FUNC * gdd_func = &gdd_func_dio; static const T_GDD_DIO_CAP gdd_dio_cap = { GDD_MTU_SIZE }; /** Local structure for maintaining the test connections */ typedef struct { T_GDD_CON_HANDLE con_handle; T_GDD_BUF * send_buf; T_GDD_BUF * rcv_buf; int cnt_sigtype_send_buf_available; } APP_GDD_CON_TABLE_ENTRY; static APP_GDD_CON_TABLE_ENTRY con_table[TEST_MAX_CON]; /*==== Local functions =======================================================*/ /** Create capabilities structure */ static T_GDD_CAP gdd_create_capabilities_300() { T_GDD_CAP cap; cap.dio_cap = gdd_dio_cap; return cap; } static void app_gdd_setup_segment(U8 * ptr, U16 size, U16 offset) { int i; for(i=0; i < size; ++i) { ptr[i] = (U8)i + offset; } } /** Setup the data bytes in provided buffer in order to create * a well-defined test buffer. The test data is created according * to a simple algorithm. The size is also used as an offset * in the algorithm. */ void app_gdd_setup_test_buffer(T_GDD_BUF * buf, U16 size) { void * tmp_buf; MALLOC(tmp_buf, size); app_gdd_setup_segment(tmp_buf, size, size); if(gdd_write_buf(tmp_buf, size, buf) < 0) { TRACE_ASSERT(0); } MFREE(tmp_buf); } /** Verify the integrity of a test buffer that has been created * before with the function app_gdd_setup_test_buffer(). * * Return TRUE if two buffers are the same, FALSE otherwise */ BOOL app_gdd_verify_test_buffer(const T_GDD_BUF * buf, U16 size) { char * tmp_buf_ref; char * tmp_buf_received; MALLOC(tmp_buf_ref, size); MALLOC(tmp_buf_received, size); app_gdd_setup_segment((U8 *)tmp_buf_ref, size, size); if(gdd_read_buf(buf, (U8 *)tmp_buf_received, size) < 0) { TRACE_ASSERT(0); } if(memcmp(tmp_buf_ref, tmp_buf_received, size)) { return FALSE; } return TRUE; } /** Convert from instance string representation to the numeric instance number */ int get_inst_num(const char * str) { if(!strncmp("BAT", str, 3)) return GDD_INST_BAT; else if(!strncmp("APP", str, 3)) return GDD_INST_APP; else if(!strncmp("TCP", str, 3)) return GDD_INST_TCP; else if(!strncmp("SOCK", str, 4)) return GDD_INST_SOCK; else if(!strncmp("SOCKCFG", str, 7)) return GDD_INST_SOCKCFG; else return -1; /* invalid instance */ } /* For Target, we must include the two DIO buffer helper functions, because we don't include the PSI stub, where they reside for simulation build. */ #if defined (_TARGET_) void copy_dio_buf(const T_dio_buffer * buf_in, T_dio_buffer ** buf_out) { int i; T_dio_segment * seg_in; T_dio_segment * seg_out; TRACE_FUNCTION( "copy_dio_buf" ); /* Allocate new buffer */ MALLOC((*buf_out), (USHORT)sizeof(T_dio_buffer)); (*buf_out)->c_dio_segment = buf_in->c_dio_segment; (*buf_out)->length=buf_in->length; /* allocate segement array and copy data accross */ MALLOC((*buf_out)->ptr_dio_segment,(USHORT)sizeof(T_dio_segment)*buf_in->c_dio_segment); memcpy((*buf_out)->ptr_dio_segment,buf_in->ptr_dio_segment,(USHORT)sizeof(T_dio_segment)*buf_in->c_dio_segment); (*buf_out)->c_dio_segment = buf_in->c_dio_segment; /* Copy each segment */ seg_in = buf_in->ptr_dio_segment; seg_out = (*buf_out)->ptr_dio_segment; for(i=0;i<buf_in->c_dio_segment;++i, ++seg_in, ++seg_out ) { seg_out->c_data = seg_in->c_data; MALLOC(seg_out->ptr_data, seg_out->c_data); memcpy(seg_out->ptr_data, seg_in->ptr_data, seg_out->c_data); } TRACE_EVENT_P1("Allocated new DIO buffer %x", *buf_out); } #define TEM__GDD_DIO_MTU_SIZE_MAX 1500 void allocate_rx_dio_buf(T_dio_buffer ** buf_out) { const U16 segments[] = {2, TEM__GDD_DIO_MTU_SIZE_MAX}; TRACE_FUNCTION( "allocate_rx_dio_buf" ); allocate_dio_buf(buf_out, segments, 2); } void allocate_dio_buf(T_dio_buffer ** buf_out, const U16 seg_size[], U16 num_seg) { int idx_seg; TRACE_FUNCTION( "allocate_rx_dio_buf" ); /* allocate segement array and copy data accross */ MALLOC(*buf_out, (USHORT)sizeof(T_dio_buffer)); (*buf_out)->c_dio_segment = (U8)num_seg; MALLOC((*buf_out)->ptr_dio_segment,(USHORT)sizeof(T_dio_segment)*(*buf_out)->c_dio_segment); (*buf_out)->length = 0; for(idx_seg=0; idx_seg<num_seg; ++idx_seg) { T_dio_segment * seg = &((*buf_out)->ptr_dio_segment[idx_seg]); seg->c_data = seg_size[idx_seg]; MALLOC(seg->ptr_data, seg->c_data); (*buf_out)->length += seg->c_data; } } void free_dio_buf(T_dio_buffer ** buf) { int i; T_dio_segment * seg = (*buf)->ptr_dio_segment; TRACE_FUNCTION( "free_dio_buf" ); /* Free each segement */ for(i=0;i<(*buf)->c_dio_segment; ++i, ++seg) { if (seg->ptr_data NEQ NULL) MFREE(seg->ptr_data); } /* Free segment array */ if ((*buf)->ptr_dio_segment NEQ NULL) MFREE((*buf)->ptr_dio_segment); /* Free the actual buffer */ MFREE(*buf); (*buf) = 0; } #endif /* (_TARGET_) */ /*--------------------------------------------------------------------------- * GDD callbacks *---------------------------------------------------------------------------*/ /** gdd_receive_data_cb */ GDD_RESULT app_gdd_receive_data_cb ( T_GDD_CON_HANDLE con_handle, T_GDD_BUF * buf ) { int i; TRACE_FUNCTION("app_gdd_receive_data_cb"); /* Search connection slot */ for(i = 0; i < TEST_MAX_CON; ++i) { if(con_table[i].con_handle EQ con_handle) { T_GDD_BUF * new_buf; if(con_table[i].rcv_buf) { TRACE_ERROR("Receive buffer already in use"); return GDD_INTERNAL_ERROR; } /* Create a copy of the buffer */ copy_dio_buf( (const T_dio_buffer *)buf, (T_dio_buffer **)(&new_buf)); con_table[i].rcv_buf = new_buf; return GDD_OK; } } TRACE_ERROR("callback called with bad connection handle"); return GDD_INTERNAL_ERROR; } /** gdd_signal_cb */ GDD_RESULT app_gdd_signal_cb ( T_GDD_CON_HANDLE con_handle, T_GDD_SIGNAL sig ) { int i; TRACE_FUNCTION("app_gdd_signal_cb"); /* Search connection slot */ for(i = 0; i < TEST_MAX_CON; ++i) { if(con_table[i].con_handle EQ con_handle) { if(sig.sig EQ GDD_SIGTYPE_SEND_BUF_AVAILABLE) { ++con_table[i].cnt_sigtype_send_buf_available; } /* Processing of other signals goes here ... */ return GDD_OK; } } /* In case of the connection signal, we might not have a connection slot at this stage, this it is not considered an error. */ if( sig.sig NEQ GDD_SIGTYPE_CONNECTION_OPENED ) TRACE_ERROR("callback called with bad connection handle"); return GDD_INTERNAL_ERROR; } /*--------------------------------------------------------------------------- * Definition of command handler functions *---------------------------------------------------------------------------*/ static char *app_gdd_init (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; char * mem = 0; int num_con = get_item(argv[2], 4, TRUE); int inst_id = get_inst_num(argv[1]); if(inst_id < 0) { TRACE_ERROR("Invalid instance specified"); BAT_TEST_FAILED(); return 0; } TRACE_FUNCTION("app_gdd_init"); if(argv[3] && !strcmp(string_to_lower(argv[3]), "YES")) { MALLOC(mem, num_con * GDD_DIO_SIZEOF_CONDATA); } result = gdd_func->gdd_init((T_GDD_INST_ID)inst_id, (char*)mem, (U16)num_con) ; if(result != GDD_OK) { TRACE_ERROR("Call to gdd_init failed"); BAT_TEST_FAILED(); return 0; } BAT_TEST_PASSED(); return 0; } static char *app_gdd_deinit (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; int inst_id = get_inst_num(argv[1]); if(inst_id < 0) { TRACE_ERROR("Invalid instance specified"); BAT_TEST_FAILED(); return 0; } TRACE_FUNCTION("app_gdd_deinit"); result =(GDD_RESULT)gdd_func->gdd_deinit((T_GDD_INST_ID)inst_id) ; if(result != GDD_OK) { TRACE_ERROR("Call to gdd_deinit failed"); BAT_TEST_FAILED(); return 0; } BAT_TEST_PASSED(); return 0; } static char *app_gdd_connect (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; int i = 0; const T_GDD_CAP gdd_cap = gdd_create_capabilities_300(); int inst_id = get_inst_num(argv[1]); if(inst_id < 0) { TRACE_ERROR("Invalid instance specified"); BAT_TEST_FAILED(); return 0; } TRACE_FUNCTION("app_gdd_connect"); /* Find free slot for connection handle */ while(i < TEST_MAX_CON && con_table[i].con_handle != 0) { ++i; } if(i EQ TEST_MAX_CON) { TRACE_ERROR("No free slot for connection handle"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_connect ((T_GDD_INST_ID)inst_id, &(con_table[i].con_handle), &gdd_cap,(T_GDD_RECEIVE_DATA_CB)app_gdd_receive_data_cb,(T_GDD_SIGNAL_CB) app_gdd_signal_cb); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_connect failed"); BAT_TEST_FAILED(); return 0; } BAT_TEST_PASSED(); return 0; } static char *app_gdd_disconnect (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; int con_num; /* connection number -index into local static connection table */ TRACE_FUNCTION("app_gdd_disconnect"); con_num = get_item(argv[1], 0, FALSE); if(con_num >= TEST_MAX_CON) { TRACE_ERROR("Connection number out of bounds"); BAT_TEST_FAILED(); return 0; } if(con_table[con_num].con_handle EQ 0) { TRACE_ERROR("Connection number not valid - no connection handle"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_disconnect(con_table[con_num].con_handle); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_disconnect failed"); BAT_TEST_FAILED(); return 0; } /* Free our application buffers which we have allocated ourselfs */ if(con_table[con_num].rcv_buf) { free_dio_buf((T_dio_buffer **)(&con_table[con_num].rcv_buf)); con_table[con_num].rcv_buf = 0; } con_table[con_num].con_handle = 0; BAT_TEST_PASSED(); return 0; } static char *app_gdd_get_send_buffer (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; int con_num; /* connection number -index into local static connection table */ int num_bytes; T_GDD_BUF * buf; TRACE_FUNCTION("app_gdd_get_send_buffer"); con_num = get_item(argv[1], 0, TRUE); if(con_num >= TEST_MAX_CON) { TRACE_ERROR("Connection number out of bounds"); BAT_TEST_FAILED(); return 0; } if(con_table[con_num].con_handle EQ 0) { TRACE_ERROR("Connection number not valid - no connection handle"); BAT_TEST_FAILED(); return 0; } num_bytes = get_item(argv[2], 100, FALSE); result = gdd_func->gdd_get_send_buffer(con_table[con_num].con_handle, &buf, (U16)num_bytes); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_get_send_buffer failed"); BAT_TEST_FAILED(); return 0; } con_table[con_num].send_buf = buf; BAT_TEST_PASSED(); return 0; } static char *app_gdd_send_data (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; int con_num; /* connection number -index into local static connection table */ int num_bytes; T_GDD_BUF * buf; TRACE_FUNCTION("app_gdd_send_data"); con_num = get_item(argv[1], 0, TRUE); if(con_num >= TEST_MAX_CON) { TRACE_ERROR("Connection number out of bounds"); BAT_TEST_FAILED(); return 0; } if(con_table[con_num].con_handle EQ 0) { TRACE_ERROR("Connection number not valid - no connection handle"); BAT_TEST_FAILED(); return 0; } buf = con_table[con_num].send_buf; if(buf EQ 0) { TRACE_ERROR("No buffer for sending"); BAT_TEST_FAILED(); return 0; } num_bytes = get_item(argv[2], 100, FALSE); app_gdd_setup_test_buffer(buf, (U16)num_bytes); result = gdd_func->gdd_send_data(con_table[con_num].con_handle, buf); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_get_send_buffer failed"); BAT_TEST_FAILED(); return 0; } con_table[con_num].send_buf = 0; BAT_TEST_PASSED(); return 0; } static char *app_gdd_receive_data (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { int con_num; /* connection number -index into local static connection table */ int num_bytes; T_GDD_BUF * buf; TRACE_FUNCTION("app_gdd_receive_data"); con_num = get_item(argv[1], 0, FALSE); if(con_num >= TEST_MAX_CON) { TRACE_ERROR("Connection number out of bounds"); BAT_TEST_FAILED(); return 0; } if(con_table[con_num].con_handle EQ 0) { TRACE_ERROR("Connection number not valid - no connection handle"); BAT_TEST_FAILED(); return 0; } buf = con_table[con_num].rcv_buf; if(buf EQ 0) { TRACE_ERROR("No buffer received"); BAT_TEST_FAILED(); return 0; } num_bytes = get_item(argv[2], 100, FALSE); /* Compare/verify the received buffer */ if(app_gdd_verify_test_buffer(buf, (U16)num_bytes) EQ FALSE) { TRACE_ERROR("Verification of received buffer failed"); BAT_TEST_FAILED(); return 0; } /* Free our application buffers which we have allocated ourselfs */ if(con_table[con_num].rcv_buf) { free_dio_buf((T_dio_buffer **)(&con_table[con_num].rcv_buf)); con_table[con_num].rcv_buf = 0; } BAT_TEST_PASSED(); return 0; } static char *app_gdd_sig_ready_rcv (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { int con_num; /* connection number -index into local static connection table */ TRACE_FUNCTION("app_gdd_sig_ready_rcv"); con_num = get_item(argv[1], 0, FALSE); if(con_num >= TEST_MAX_CON) { TRACE_ERROR("Connection number out of bounds"); BAT_TEST_FAILED(); return 0; } if(con_table[con_num].con_handle EQ 0) { TRACE_ERROR("Connection number not valid - no connection handle"); BAT_TEST_FAILED(); return 0; } gdd_func->gdd_signal_ready_rcv(con_table[con_num].con_handle); BAT_TEST_PASSED(); return 0; } static char *app_gdd_init_test_parms (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; TRACE_FUNCTION("app_gdd_init_test_parms"); /* * Test range of user ID */ /*lint -e778*/ result = gdd_func->gdd_init(GDD_INST_NONE, (void *)0, (U16)4) ; if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (user = GDD_INST_BAT - 1)"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_init(GDD_NUM_INSTS, 0, 4); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (user = GDD_NUM_INSTS)"); BAT_TEST_FAILED(); return 0; } /* * Nothing to do for the mem parameter * (should already have been tested before) */ /* * Test number of connections */ result = gdd_func->gdd_init(GDD_INST_BAT, 0, 0); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (num_con = 0)"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_init(GDD_INST_BAT, 0, TEST_MAX_CON+1); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (num_con = TEST_MAX_CON+1)"); BAT_TEST_FAILED(); return 0; } BAT_TEST_PASSED(); return 0; } static char *app_gdd_deinit_test_parms (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; TRACE_FUNCTION("app_gdd_deinit_test_parms"); /* * Test range of user ID */ result = gdd_func->gdd_deinit(GDD_INST_NONE) ; /*lint -e778*/ if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (user = GDD_INST_BAT - 1)"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_deinit(GDD_NUM_INSTS); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (user = GDD_NUM_INSTS)"); BAT_TEST_FAILED(); return 0; } BAT_TEST_PASSED(); return 0; } static char *app_gdd_connect_test_parms (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; const T_GDD_CAP gdd_cap = gdd_create_capabilities_300(); TRACE_FUNCTION("app_gdd_connect_test_parms"); /* * Test range of user ID */ result = gdd_func->gdd_connect(GDD_INST_NONE, &(con_table[0].con_handle), /*lint -e778*/ &gdd_cap, (T_GDD_RECEIVE_DATA_CB)app_gdd_receive_data_cb, (T_GDD_SIGNAL_CB)app_gdd_signal_cb); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (user = GDD_INST_BAT - 1)"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_connect(GDD_NUM_INSTS, &(con_table[0].con_handle), &gdd_cap, (T_GDD_RECEIVE_DATA_CB)app_gdd_receive_data_cb, (T_GDD_SIGNAL_CB)app_gdd_signal_cb); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (user = GDD_NUM_INSTS)"); BAT_TEST_FAILED(); return 0; } /* Test handling of con_handle = 0 */ result = gdd_func->gdd_connect(GDD_INST_BAT, 0, &gdd_cap, (T_GDD_RECEIVE_DATA_CB)app_gdd_receive_data_cb, (T_GDD_SIGNAL_CB)app_gdd_signal_cb); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (con_handle = 0)"); BAT_TEST_FAILED(); return 0; } /* Test handling of cap = 0 */ result = gdd_func->gdd_connect(GDD_INST_BAT, &(con_table[0].con_handle), 0, (T_GDD_RECEIVE_DATA_CB)app_gdd_receive_data_cb, (T_GDD_SIGNAL_CB)app_gdd_signal_cb); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (cap = 0)"); BAT_TEST_FAILED(); return 0; } /* Test handling of rcv_cb = 0 */ result = gdd_func->gdd_connect(GDD_INST_BAT, &(con_table[0].con_handle), &gdd_cap, 0,(T_GDD_SIGNAL_CB) app_gdd_signal_cb); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (rcv_cb = 0)"); BAT_TEST_FAILED(); return 0; } /* Test handling of sig_cb = 0 */ result = gdd_func->gdd_connect(GDD_INST_BAT, &(con_table[0].con_handle), &gdd_cap, app_gdd_receive_data_cb, 0); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (sig_cb = 0)"); BAT_TEST_FAILED(); return 0; } BAT_TEST_PASSED(); return 0; } static char *app_gdd_disconnect_test_parms (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; TRACE_FUNCTION("app_gdd_disconnect_test_parms"); /* Test handling of con_handle = 0 */ result = gdd_func->gdd_disconnect(0); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (con_handle = 0)"); BAT_TEST_FAILED(); return 0; } BAT_TEST_PASSED(); return 0; } static char *app_gdd_get_send_buffer_test_parms (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; T_GDD_BUF * buf; TRACE_FUNCTION("app_gdd_get_send_buffer_test_parms"); /* Test handling of con_handle = 0 */ result = gdd_func->gdd_get_send_buffer(0, &buf, GDD_MTU_SIZE); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (con_handle = 0)"); BAT_TEST_FAILED(); return 0; } /* Test handling of buf = 0 */ result = gdd_func->gdd_get_send_buffer(TEST_CON_HANDLE, 0, GDD_MTU_SIZE); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (buf = 0)"); BAT_TEST_FAILED(); return 0; } /* Test handling of size = 0 */ result = gdd_func->gdd_get_send_buffer(TEST_CON_HANDLE, &buf, 0); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (size = 0)"); BAT_TEST_FAILED(); return 0; } /* Test handling of size > GDD_MTU_SIZE */ result = gdd_func->gdd_get_send_buffer(TEST_CON_HANDLE, &buf, GDD_MTU_SIZE+1); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (size = GDD_MTU_SIZE+1)"); BAT_TEST_FAILED(); return 0; } BAT_TEST_PASSED(); return 0; } static char *app_gdd_send_data_test_parms (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; T_GDD_BUF buf; TRACE_FUNCTION("app_gdd_send_data_test_parms"); /* Test handling of con_handle = 0 */ result = gdd_func->gdd_send_data(0, &buf); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (con_handle = 0)"); BAT_TEST_FAILED(); return 0; } /* Test handling of buf = 0 */ result = gdd_func->gdd_send_data(TEST_CON_HANDLE, 0); if(result NEQ GDD_INVALID_PARAMS) { TRACE_ERROR("BAD param value *NOT* detected (buf = 0)"); BAT_TEST_FAILED(); return 0; } BAT_TEST_PASSED(); return 0; } /* * Test connect, followed by immedate disconnect without waiting for connect signal */ static char *app_gdd_immediate_disconnect (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; int con_idx = 0; int user_id = get_item(argv[1], GDD_INST_BAT, TRUE); const T_GDD_CAP gdd_cap = gdd_create_capabilities_300(); TRACE_FUNCTION("app_gdd_immediate_disconnect"); /* Find free slot for connection handle */ while(con_idx < TEST_MAX_CON && con_table[con_idx].con_handle != 0) { ++con_idx; } if(con_idx EQ TEST_MAX_CON) { TRACE_ERROR("No free slot for connection handle"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_connect ((T_GDD_INST_ID)user_id, &(con_table[con_idx].con_handle), &gdd_cap, (T_GDD_RECEIVE_DATA_CB) app_gdd_receive_data_cb, (T_GDD_SIGNAL_CB)app_gdd_signal_cb); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_connect failed"); BAT_TEST_FAILED(); return 0; } TRACE_EVENT_P2("Created connection, con_handle = %d (slot %d)", con_table[con_idx].con_handle, con_idx); /* Don't sleep - but you might want to activate for debugging */ /*vsi_t_sleep (VSI_CALLER 2000);*/ result = gdd_func->gdd_disconnect(con_table[con_idx].con_handle); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_disconnect failed"); BAT_TEST_FAILED(); return 0; } TRACE_EVENT_P1("Disconnected connection, con_handle = %d", con_table[con_idx].con_handle); /* Free connection slot */ con_table[con_idx].con_handle = 0; BAT_TEST_PASSED(); return 0; } #ifdef WIN32 /* * The the correct sending of the signal GDD_SIGTYPE_SEND_BUF_AVAILABLE */ static char *app_gdd_test_sig_sbuf_avail (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { GDD_RESULT result; T_GDD_BUF * buf1, * buf2, * buf3; int con_idx = 0; int user_id = get_item(argv[1], GDD_INST_BAT, TRUE); const T_GDD_CAP gdd_cap = gdd_create_capabilities_300(); TRACE_FUNCTION("app_gdd_test_sig_sbuf_avail"); /* Switch off the automatic provision of send buffers in the PSI stub */ psi_stub_send_rx_buf_after_read(FALSE); /* Find free slot for connection handle */ while(con_idx < TEST_MAX_CON && con_table[con_idx].con_handle != 0) { ++con_idx; } if(con_idx EQ TEST_MAX_CON) { TRACE_ERROR("No free slot for connection handle"); BAT_TEST_FAILED(); return 0; } /* Connect & disconnect */ result = gdd_func->gdd_connect (user_id, &(con_table[con_idx].con_handle), &gdd_cap, app_gdd_receive_data_cb, app_gdd_signal_cb); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_connect failed"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_disconnect(con_table[con_idx].con_handle); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_disconnect failed"); BAT_TEST_FAILED(); return 0; } /* Reset test counter */ con_table[con_idx].cnt_sigtype_send_buf_available = 0; /* Create connection */ result = gdd_func->gdd_connect (user_id, &(con_table[con_idx].con_handle), &gdd_cap, app_gdd_receive_data_cb, app_gdd_signal_cb); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_connect failed"); BAT_TEST_FAILED(); return 0; } TRACE_EVENT_P2("Created connection, con_handle = %d (slot %d)", con_table[con_idx].con_handle, con_idx); /* Wait for 2 seconds to be sure that we will have the send buffer by then. */ vsi_t_sleep (VSI_CALLER 2000); /* Get a first send buffer */ result = gdd_func->gdd_get_send_buffer(con_table[con_idx].con_handle, &buf1, GDD_MTU_SIZE); if(result NEQ GDD_OK) { TRACE_ERROR("Error: gdd_get_send_buffer() failed"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_get_send_buffer(con_table[con_idx].con_handle, &buf2, GDD_MTU_SIZE); if(result NEQ GDD_NO_BUF_AVAILABLE) { TRACE_ERROR("gdd_get_send_buffer() did not fail as expected"); BAT_TEST_FAILED(); return 0; } /* Now we send back the first buffer. */ result = gdd_func->gdd_send_data(con_table[con_idx].con_handle, buf1); if(result NEQ GDD_OK) { TRACE_ERROR("gdd_send_data() failed"); BAT_TEST_FAILED(); return 0; } /* Now we can get the second send buffer */ result = gdd_func->gdd_get_send_buffer(con_table[con_idx].con_handle, &buf2, GDD_MTU_SIZE); if(result NEQ GDD_OK) { TRACE_ERROR("gdd_get_send_buffer failed"); BAT_TEST_FAILED(); return 0; } /* Remove the receive buffer previously received */ free_dio_buf((T_dio_buffer **)(&con_table[con_idx].rcv_buf)); con_table[con_idx].rcv_buf = 0; /* Now we send back the 2nd buffer buffer. */ result = gdd_func->gdd_send_data(con_table[con_idx].con_handle, buf2); if(result NEQ GDD_OK) { TRACE_ERROR("gdd_send_data() failed"); BAT_TEST_FAILED(); return 0; } /* When we try to get the third buffer, we should now fail, as we switched of automatic provision of RX buffers at the beginning */ result = gdd_func->gdd_get_send_buffer(con_table[con_idx].con_handle, &buf3, GDD_MTU_SIZE); if(result NEQ GDD_NO_BUF_AVAILABLE) { TRACE_ERROR("gdd_get_send_buffer should have failed with GDD_NO_BUF_AVAILABLE"); BAT_TEST_FAILED(); return 0; } /* Create a new RX buffer in the PSI stub */ psi_stub_provide_rx_buf(); /* Now we should be able to get the new buffer */ result = gdd_func->gdd_get_send_buffer(con_table[con_idx].con_handle, &buf3, GDD_MTU_SIZE); if(result NEQ GDD_OK) { TRACE_ERROR("gdd_get_send_buffer failed"); BAT_TEST_FAILED(); return 0; } /* Two signals GDD_SIGTYPE_SEND_BUF_AVAILABLE should have been sent (one after the connection, and one when we called pst_stub_provide_rx_buf the last time) */ if(con_table[con_idx].cnt_sigtype_send_buf_available NEQ 1) { TRACE_ERROR("Wrong value in cnt_sigtype_send_buf_available"); BAT_TEST_FAILED(); return 0; } result = gdd_func->gdd_disconnect(con_table[con_idx].con_handle); if(result != GDD_OK) { TRACE_ERROR("Call to gdd_disconnect failed"); BAT_TEST_FAILED(); return 0; } TRACE_EVENT_P1("Disconnected connection, con_handle = %d", con_table[con_idx].con_handle); /* Free connection slot */ con_table[con_idx].con_handle = 0; /* Switch on the automatic provision of send buffers in the PSI stub */ psi_stub_send_rx_buf_after_read(TRUE); BAT_TEST_PASSED(); return 0; } #endif /* WIN32 */ /*--------------------------------------------------------------------------- * Testing helper functions. *---------------------------------------------------------------------------*/ static U32 test_gdd_write_buf() { T_dio_buffer * dest_buf; char src_buf[250]; allocate_rx_dio_buf(&dest_buf); if(dest_buf->c_dio_segment != 2) { return((U32) -1); } if(dest_buf->length < (sizeof(src_buf) + 2 /*PID*/)) { return((U32) -1); } app_gdd_setup_segment((U8 *)src_buf, sizeof(src_buf), 22 /* arbitrary offset */); if(gdd_write_buf(( U8 *)src_buf, sizeof(src_buf), (T_GDD_BUF*)dest_buf) < 0) { return((U32) -1); } if(memcmp(src_buf, dest_buf->ptr_dio_segment[1].ptr_data, sizeof(src_buf))) { return((U32) -1); } return 0; } /* * Test the function 'gdd_read_buf()'. Return 0 if OK. */ static U32 test_gdd_read_buf() { char src_buf[500]; char dest_buf[500]; T_dio_buffer * dio_buf; /* Totol size of 502 bytes over 6 segments (incl.PID in first seg) */ const U16 segments[] = {2, 15, 150, 35, 100, 200}; allocate_dio_buf(&dio_buf, segments, sizeof(segments)/sizeof(U16)); app_gdd_setup_segment((U8 *)src_buf, sizeof(src_buf), 22 /* arbitrary offset */); if(gdd_write_buf((U8 *)src_buf, sizeof(src_buf), (T_GDD_BUF*)dio_buf) < 0) { return((U32)-1); } if(gdd_read_buf((T_GDD_BUF*)dio_buf, (U8 *)dest_buf, sizeof(dest_buf)) < 0) { return((U32) -1); } if(memcmp(src_buf, dest_buf, sizeof(src_buf))) { return((U32)-1); } return 0; } static char *app_gdd_test_helper_functions (app_cmd_entry_t *cmd_entry_ptr, int argc, char * argv[], core_func_t core_func) { if(test_gdd_write_buf()) { BAT_TEST_FAILED(); } if(test_gdd_read_buf()) { BAT_TEST_FAILED(); } BAT_TEST_PASSED(); return 0; } /*--------------------------------------------------------------------------- * Definition of core functions *---------------------------------------------------------------------------*/ /* -- No core functions required for now */ /*==== Exported functions ====================================================*/ char *app_handle_command_gdd(char *command) { return app_handle_command(command, app_gdd_cmd_table); } /* EOF */