/***************************************************************************** * aft_api.c AFT T1/E1: HDLC API Sample Code * * Author(s): Nenad Corbic * * Copyright: (c) 2003-2004 Sangoma Technologies Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "lib_api.h" #define MAX_TX_DATA 1024*10 /* Size of tx data */ #define MAX_FRAMES 5000 /* Number of frames to transmit */ #define MAX_RX_DATA 1024*10 unsigned short Rx_lgth; unsigned char Rx_data[MAX_RX_DATA]; unsigned char Tx_data[MAX_TX_DATA + sizeof(api_tx_hdr_t)]; /* Prototypes */ int MakeConnection(void); void handle_socket( void); void sig_end(int sigid); int sock; FILE *tx_fd=NULL,*rx_fd=NULL; /*************************************************** * MakeConnection * * o Create a Socket * o Bind a socket to a wanpipe network interface * (Interface name is supplied by the user) */ void print_packet(unsigned char *buf, int len) { int x; printf("{ | "); for (x=0;xdata[i] = (unsigned char)i; }else{ #if 0 api_tx_el->data[i] = (unsigned char)tx_data+(i%4); #else api_tx_el->data[i] = (unsigned char)tx_data; #endif } } } /* Main Rx Tx OOB routine */ for(;;) { /* Initialize all select() descriptors */ FD_ZERO(&ready); FD_ZERO(&write); FD_ZERO(&oob); FD_SET(sock,&oob); FD_SET(sock,&ready); if (write_enable){ FD_SET(sock,&write); } /* Select will block, until: * 1: OOB event, link level change * 2: Rx data available * 3: Interface able to Tx */ if(select(sock + 1,&ready, &write, &oob, NULL)){ fflush(stdout); if (FD_ISSET(sock,&oob)){ /* An OOB event is pending, usually indicating * a link level change */ err = recv(sock, Rx_data, MAX_RX_DATA, MSG_OOB); if(err < 0 ) { printf("Failed to receive OOB %i , %i\n", Rx_count, err); err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); printf("Sock state is %s\n", (err == 0) ? "CONNECTED" : (err == 1) ? "DISCONNECTED" : "CONNECTING"); break; } printf("GOT OOB EXCEPTION CMD Exiting\n"); break; } if (FD_ISSET(sock,&ready)){ /* An Rx packet is pending * 1: Read the rx packet into the Rx_data * buffer. Confirm len > 0 * * 2: Cast Rx_data to the api_rx_element. * Thus, removing a 16 byte header * attached by the driver. * * 3. Check error_flag: * CRC,Abort..etc */ memset(Rx_data, 0, sizeof(Rx_data)); #if 1 err = sangoma_readmsg_socket(sock, Rx_data,16, &Rx_data[16], MAX_RX_DATA-16, 0); #else err = sangoma_read_socket(sock, Rx_data, MAX_RX_DATA, 0); #endif if (!read_enable){ goto bitstrm_skip_read; } /* err indicates bytes received */ if(err <= 0) { printf("\nError receiving data\n"); break; } api_rx_el = (api_rx_element_t*)&Rx_data[0]; /* Check the packet length */ Rx_lgth = err - sizeof(api_rx_hdr_t); if(Rx_lgth<=0) { printf("\nShort frame received (%d)\n", Rx_lgth); return; } if (api_rx_el->api_rx_hdr.error_flag){ printf("Data: "); for(i=0;iapi_rx_hdr.error_flag & (1<api_rx_hdr.error_flag,Rx_lgth); continue; } if (api_rx_el->api_rx_hdr.error_flag & (1<api_rx_hdr.error_flag,Rx_lgth); continue; } if (api_rx_el->api_rx_hdr.error_flag & (1<api_rx_hdr.error_flag,Rx_lgth); continue; } #if 0 if (api_rx_el->data[0] == tx_data && api_rx_el->data[1] == (tx_data+1)){ if (!stream_sync){ printf("GOT SYNC %x\n",api_rx_el->data[0]); } stream_sync=1; }else{ if (stream_sync){ printf("OUT OF SYNC: %x\n",api_rx_el->data[0]); } } #endif if ((files_used & RX_FILE_USED) && rx_fd){ fwrite((void*)&Rx_data[sizeof(api_rx_hdr_t)], sizeof(char), Rx_lgth, rx_fd); } ++Rx_count; //printf("RECEIVE:\n"); //print_packet(&Rx_data[16],Rx_lgth); if (verbose){ printf("Received %i Olen=%i Length = %i\n", Rx_count, err,Rx_lgth); #if 1 printf("Data: "); for(i=0;idata[i]); } printf("\n"); #endif }else{ //putchar('R'); } if (rx_cnt > 0 && Rx_count >= rx_cnt){ break; } bitstrm_skip_read: ; } if (FD_ISSET(sock,&write)){ if (Tx_count == 0){ //printf("SEND: Len=%i\n",Tx_length); //print_packet(&Tx_data[16],Tx_length); } #if 1 err = sangoma_sendmsg_socket(sock, Tx_data,16, &Tx_data[16], Tx_length, 0); #else err = sangoma_send_socket(sock,Tx_data, Tx_length + sizeof(api_tx_hdr_t), 0); #endif if (err <= 0){ if (errno == EBUSY){ if (verbose){ printf("Sock busy try again!\n"); } /* Socket busy try sending again !*/ }else{ /* Check socket state */ err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); printf("Sock state is %s\n", (err == 0) ? "CONNECTED" : (err == 1) ? "DISCONNECTED" : "CONNECTING"); printf("Failed to send errno=%i len=%i \n",errno,Tx_length); perror("Send: "); break; } }else{ ++Tx_count; if (verbose){ printf("Packet sent: Sent %i : %i\n", err,Tx_count); }else{ //putchar('T'); } if ((files_used & TX_FILE_USED) && tx_fd){ rlen=fread((void*)&Tx_data[sizeof(api_tx_hdr_t)], sizeof(char), Tx_length,tx_fd); if (!rlen){ printf("\nTx of file %s is done!\n", tx_file); break; } if (Tx_length != rlen){ Tx_length = rlen; } } } } if (tx_delay){ usleep(tx_delay); } if (tx_cnt && tx_size && Tx_count >= tx_cnt && !(files_used & TX_FILE_USED)){ write_enable=0; if (rx_cnt > 0){ /* Dont break let rx finish */ }else{ break; } } } } if (tx_fd){ fclose(tx_fd); } if (rx_fd){ fclose(rx_fd); } close (sock); } /*************************************************************** * Main: * * o Make a socket connection to the driver. * o Call handle_socket() to read the socket * **************************************************************/ int main(int argc, char* argv[]) { int proceed; proceed=init_args(argc,argv); if (proceed != WAN_TRUE){ usage(argv[0]); return -1; } signal(SIGINT,&sig_end); proceed = MakeConnection(); if( proceed == WAN_TRUE){ handle_socket(); return 0; } return 0; }; void sig_end(int sigid) { printf("Got Signal %i\n",sigid); if (tx_fd){ fclose(tx_fd); } if (rx_fd){ fclose(rx_fd); } if (sock){ close (sock); } exit(1); }