FreeCalypso > hg > fc-selenite
diff src/g23m-fad/app/app_gdd.c @ 1:d393cd9bb723
src/g23m-*: initial import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 15 Jul 2018 04:40:46 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-fad/app/app_gdd.c Sun Jul 15 04:40:46 2018 +0000 @@ -0,0 +1,1315 @@ +/* ++------------------------------------------------------------------------------ +| 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 */