From ce0cb9660ff8345118a4c4ff7ba244d99b35a158 Mon Sep 17 00:00:00 2001 From: Iampete1 Date: Mon, 25 May 2020 16:08:04 +0100 Subject: [PATCH] SITL: examples: add MATLAB TCP/UDP/IP Toolbox --- .../GNU_General_Public_License.txt | 344 +++++ .../JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.c | 1266 +++++++++++++++++ .../JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.m | 234 +++ .../JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.mexw64 | Bin 0 -> 30720 bytes .../JSON/MATLAB/tcp_udp_ip_2.0.6/whatsnew.txt | 90 ++ 5 files changed, 1934 insertions(+) create mode 100644 libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/GNU_General_Public_License.txt create mode 100644 libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.c create mode 100644 libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.m create mode 100644 libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.mexw64 create mode 100644 libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/whatsnew.txt diff --git a/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/GNU_General_Public_License.txt b/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/GNU_General_Public_License.txt new file mode 100644 index 0000000000..06d97dd938 --- /dev/null +++ b/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/GNU_General_Public_License.txt @@ -0,0 +1,344 @@ +(View this file in a web-browser if not properly displayed now.) + + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.c b/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.c new file mode 100644 index 0000000000..7d0324ff85 --- /dev/null +++ b/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.c @@ -0,0 +1,1266 @@ +/********************************************************** + + MEX file for the tcpip toolbox. + */ +#define VERSION "Version 2.0.5 2003-09-16" + +/* +% This file(s) is part of the tcp_udp_ip toolbox (C) Peter Rydesäter et al. +% et al. 1998-2003 for running in MATLAB(R) as scripts and/or plug-ins. +% +% 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. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program; if not, write to the Free Software +% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +% +% In addition, as a SPECIAL EXCEPTION, Peter Rydesäter, SWEDEN, +% gives permission to link the code of this program with any library, +% and distribute linked combinations of it. You must obey the GNU +% General Public License in all respects for all of the code in the +% tcp_udp_ip toolbox and any . If you modify any source file included, +% you may extend this exception to your version of the file, but you are +% not obligated to do so. If you do not wish to do so, delete this exception +% statement from your version. This exception makes it possible to use +% pnet.c (.dll) as a plug-in as it is intended and let it be (dynamical) +% linked to MATLAB(R) or any compiled stand alone application. + + + Notes for Unix implementation + Compile this with: + + mex -O pnet.c + + Notes for Windows implementation + + When using LCC, compile this with: + mex -O pnet.c {MATLAB_INSTALL_DIR}\sys\lcc\lib\wsock32.lib -DWIN32 + + When using Visual C++, compile this with: + mex -O pnet.c ws2_32.lib -DWIN32 + + + == Main Authour == == Windows support == == Earlie/Basic UDP support == + Peter Rydesäter Mario Bergeron Mike Medeiros at 23-Jan-2001. + LYRtech + Östersund, Sweden Québec, Canada + +46 70 560 68 16 + Peter.Rydesater@mh.se Mario.Bergeron@lyrtech.com + + + SE MORE: http://www.rydesater.com + + **********************************************************/ + +/******* GENERAL DEFINES *********/ +#include +#include +#include +#include +#include + +/******* WINDOWS ONLY DEFINES *********/ +#ifdef WIN32 +#define IFWINDOWS(dothis) dothis +#define IFUNIX(dothis) +//#include +#include +#define close(s) closesocket(s) +#define nonblockingsocket(s) {unsigned long ctl = 1;ioctlsocket( s, FIONBIO, &ctl );} +#define s_errno WSAGetLastError() +#define EWOULDBLOCK WSAEWOULDBLOCK +#define usleep(a) Sleep((a)/1000) +#define MSG_NOSIGNAL 0 + +/******* NON WINDOWS DEFINES *********/ +#else +#define IFWINDOWS(dothis) +#define IFUNIX(dothis) dothis + +#include +#define s_errno errno // ?? Is this OK ?? +#include +#include +#include +#include +#include +#include +#include +#define nonblockingsocket(s) fcntl(s,F_SETFL,O_NONBLOCK) +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE (-1) +#endif + +// Do this hack cause SIGPIPE that kills matlab on any platform??? +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +/* Include header file for matlab mex file functionality */ +#include "mex.h" + +/********** DEFINES related to pnet own functionality *****************/ +/* Set debuging on/off */ +#define debug_view_con_status(X) // __debug_view_con_status(X) + +#define MAX_CON 100 /* Maximum number of simultanius tcpip connections.*/ +#define NAMEBUFF_LEN 100 +#define MINBUFFSIZE 1000 /* readbuffer will shrink to this size if datalength is smaller. */ +#define CBNAMELEN 30 + +#define CON_FREE -1 /* Find a new free struct in struct array */ + +#define BACKLOG 50 /* How many pending connections queue will hold */ + +#define double_inf HUGE_VAL +#define DEFAULT_WRITETIMEOUT double_inf +#define DEFAULT_READTIMEOUT double_inf +#define DEFAULT_INPUT_SIZE 50000 +#define DEFAULT_USLEEP 10000 + +/* Different status of a con_info struct handles a file descriptor */ +#define STATUS_FREE -1 +#define STATUS_NOCONNECT 0 // Disconnected pipe that is note closed +#define STATUS_TCP_SOCKET 1 +#define STATUS_IO_OK 5 // Used for IS_... test +#define STATUS_UDP_CLIENT 6 +#define STATUS_UDP_SERVER 8 +#define STATUS_CONNECT 10 // Used for IS_... test +#define STATUS_TCP_CLIENT 11 +#define STATUS_TCP_SERVER 12 +#define STATUS_UDP_CLIENT_CONNECT 18 +#define STATUS_UDP_SERVER_CONNECT 19 + +#define IS_STATUS_IO_OK(x) ((x)>=STATUS_IO_OK) +#define IS_STATUS_CONNECTED(x) ((x)>=STATUS_CONNECT) +#define IS_STATUS_UDP_NO_CON(x) ((x)==STATUS_UDP_CLIENT || (x)==STATUS_UDP_SERVER) +#define IS_STATUS_TCP_CONNECTED(x) ((x)==STATUS_TCP_CLIENT || (x)==STATUS_TCP_SERVER) + +typedef struct +{ + char *ptr; /* Pointer to buffert. */ + int len; /* Length of allocated buffert. */ + int pos; /* Length used of buffer for data storage.*/ +} io_buff; + +/* Structure that hold all information about a tcpip connection. */ +typedef struct +{ + int fid; + double writetimeout; + double readtimeout; + struct sockaddr_in remote_addr; + io_buff write; + io_buff read; + int status; /* STATUS_... FREE, NOCONNECT, SERVER, CLIENT ... */ + char callback[CBNAMELEN+1]; +} con_info; + + +///////////////////////////////////////////////////////////////////////////////////////////////// +/* Some global variables */ +int gret_args=0; /* Global variable that holds number of matlab return argumens returned */ +int gnlhs; /* number of expected outputs */ +mxArray **gplhs; /* array of pointers to output arguments */ +int gnrhs; /* number of inputs */ +const mxArray **gprhs; /* array of pointers to input arguments */ + +/* Global list with static length of connections structures holding info about current connection */ +con_info con[MAX_CON]; +int con_index=0; /* Current index possition for list of handlers */ +unsigned long mex_call_counter=0; /* Counter that counts how many calls that have been done to pnet */ + +/***********************************************************************/ +void Print_Start_Message(){ + mexPrintf("\n===============================================================================\n" + "Loaded pnet MEX-file for the tcp/udp/ip-toolbox Compiled @ " + __DATE__ " " __TIME__ "\n" + VERSION "\n" + "Copyright (C) Peter Rydesäter, Sweden, et al. , 1998 - 2003\n" + "GNU General Public License, se license.txt for full license notis.\n" + "You are allowed to (dynamicaly) link this file with non-free code. \n\n" + " http://www.rydesater.com \n\n" + "===============================================================================\n\n" + ); +} + +/***********************************************************************/ +int myoptstrcmp(const char *s1,const char *s2) +{ + int val; + while( (val= toupper(*s1) - toupper(*s2))==0 ){ + if(*s1==0 || *s2==0) return 0; + s1++; + s2++; + while(*s1=='_') s1++; + while(*s2=='_') s2++; + } + return val; +} + +/********************************************************************/ +/* A "wrapper" function for memory allocation. Most for debuging /tracing purpose */ +void *myrealloc(char *ptr,int newsize) +{ + ptr=realloc(ptr,newsize); + if(ptr==NULL && newsize>0) + mexErrMsgTxt("Internal out of memory!"); + return ptr; +} + +/********************************************************************/ +/* A "wrapper" function for memory allocation. Most for debuging /tracing purpose */ +void newbuffsize(io_buff *buff,int newsize) +{ + // fprintf(stderr,"NEWSIZE:%d\n",newsize); + if(newsize==-1){ + free(buff->ptr); + buff->ptr=NULL; + return; + } + if(newsizepos) + newsize=buff->pos; + if(newsize<256) + newsize=256; + if(newsize>buff->len){ // Grow.... + // fprintf(stderr,"NEWSIZE UP %d -> %d\n",buff->len,newsize*2); + buff->ptr=myrealloc(buff->ptr,newsize*2); + buff->len=newsize*2; + }else if(newsize*4 < buff->len){ // Decrease... + // fprintf(stderr,"NEWSIZE DOWN %d -> %d\n",buff->len,newsize*2); + buff->ptr=myrealloc(buff->ptr,newsize*2); + buff->len=newsize*2; + } +} + +/********************************************************************/ +mxClassID str2classid(const char *str) +{ + if(myoptstrcmp("CHAR",str)==0) return mxCHAR_CLASS; + if(myoptstrcmp("DOUBLE",str)==0) return mxDOUBLE_CLASS; + if(myoptstrcmp("SINGLE",str)==0) return mxSINGLE_CLASS; + if(myoptstrcmp("INT8",str)==0) return mxINT8_CLASS; + if(myoptstrcmp("UINT8",str)==0) return mxUINT8_CLASS; + if(myoptstrcmp("INT16",str)==0) return mxINT16_CLASS; + if(myoptstrcmp("UINT16",str)==0) return mxUINT16_CLASS; + if(myoptstrcmp("INT32",str)==0) return mxINT32_CLASS; + if(myoptstrcmp("UINT32",str)==0) return mxUINT32_CLASS; + return mxCHAR_CLASS; // Default to char; +} + +/********************************************************************/ +mxClassID classid2size(const mxClassID id) +{ + if(id==mxCHAR_CLASS) return 1; + if(id==mxDOUBLE_CLASS) return sizeof(double); + if(id==mxSINGLE_CLASS) return sizeof(float); + if(id==mxINT8_CLASS) return 1; + if(id==mxUINT8_CLASS) return 1; + if(id==mxINT16_CLASS) return 2; + if(id==mxUINT16_CLASS) return 2; + if(id==mxINT32_CLASS) return 4; + if(id==mxUINT32_CLASS) return 4; + mexErrMsgTxt("Non supported datatype!"); + return 0; +} + +/* Windows implementation of perror() function */ +#ifdef WIN32 +/********************************************************************/ +void perror(const char *context ) +{ + int wsa_err; + wsa_err = WSAGetLastError(); + mexPrintf( "[%s]: WSA error: ", context ); + switch ( wsa_err ) + { + case WSANOTINITIALISED: mexPrintf( "WSANOTINITIALISED\n" ); break; + case WSAENETDOWN: mexPrintf( "WSAENETDOWN \n" ); break; + case WSAEADDRINUSE: mexPrintf( "WSAEADDRINUSE \n" ); break; + case WSAEACCES: mexPrintf( "WSAEACCES \n" ); break; + case WSAEINTR: mexPrintf( "WSAEINTR \n" ); break; + case WSAEINPROGRESS: mexPrintf( "WSAEINPROGRESS \n" ); break; + case WSAEALREADY: mexPrintf( "WSAEALREADY \n" ); break; + case WSAEADDRNOTAVAIL: mexPrintf( "WSAEADDRNOTAVAIL \n" ); break; + case WSAEAFNOSUPPORT: mexPrintf( "WSAEAFNOSUPPORT \n" ); break; + case WSAEFAULT: mexPrintf( "WSAEFAULT \n" ); break; + case WSAENETRESET: mexPrintf( "WSAENETRESET \n" ); break; + case WSAENOBUFS: mexPrintf( "WSAENOBUFS \n" ); break; + case WSAENOTSOCK: mexPrintf( "WSAENOTSOCK \n" ); break; + case WSAEOPNOTSUPP: mexPrintf( "WSAEOPNOTSUPP \n" ); break; + case WSAESHUTDOWN: mexPrintf( "WSAESHUTDOWN \n" ); break; + case WSAEWOULDBLOCK: mexPrintf( "WSAEWOULDBLOCK \n" ); break; + case WSAEMSGSIZE: mexPrintf( "WSAEMSGSIZE \n" ); break; + case WSAEHOSTUNREACH: mexPrintf( "WSAEHOSTUNREACH \n" ); break; + case WSAEINVAL: mexPrintf( "WSAEINVAL \n" ); break; + + case WSAECONNREFUSED: mexPrintf( "WSAECONNREFUSED \n" ); break; + case WSAECONNABORTED: mexPrintf( "WSAECONNABORTED \n" ); break; + case WSAECONNRESET: mexPrintf( "WSAECONNRESET \n" ); break; + case WSAEISCONN: mexPrintf( "WSAEISCONN \n" ); break; + case WSAENOTCONN: mexPrintf( "WSAENOTCONN \n" ); break; + case WSAETIMEDOUT: mexPrintf( "WSAETIMEDOUT \n" ); break; + default: mexPrintf( "Unknown(%d) error!\n", wsa_err ); break; + } + return; +} +#endif + +/********************************************************************/ +/*Makes byte swapping, or not depending on the mode argument */ +void byteswapdata(char *ptr,const int elements,const int elementsize,int mode) +{ + // MODE=0 Do nothing, MODE=1 Swap, MODE=2 network byte order, MODE=3 Intel byte order. +#ifndef SWAPDATA +#define SWAPDATA(a,b) { a^=b; b^=a; a^=b; } +#endif + // A little smart ckeck of byte the machine byte order. + const int ordertest=1; + const char *is_intel_order=(const char *)(&ordertest); + // fprintf(stderr,"SWAP FUNCTION...E:%d SI:%d\n",elements,elementsize); + if(elementsize<2) return; + if(is_intel_order[0]==1 && mode==2) mode=1; + if(is_intel_order[0]==0 && mode==3) mode=1; + if(mode==1){ + int e; + // fprintf(stderr,"SWAP DATA\n"); + switch(elementsize){ + case 2: for(e=0;e=MAX_CON) + mexErrMsgTxt("Unvalid value of handler!\n"); + if(idx>=0) + { + con_index=idx; + if(con[con_index].status==STATUS_FREE) + mexErrMsgTxt("No valid handler! already closed?"); + return 1; + } + debug_view_con_status("START MOVE"); + if(idx==CON_FREE) /* Move con_index until it find a free non used struct */ + { + for(con_index=0;con_indexargno) + return 1; + return 0; +} + +/******************************************************************************************************/ +/* Returns specified input argument as scalar. Global and error tolerant replacement for mxGetScalar */ +const mxArray *my_mexInputArg(const int argno) +{ + // fprintf(stderr,"GET_INPUT_ARG NO:%d\n",argno); // DEBUG + if(!my_mexIsInputArgOK(argno)) + mexErrMsgTxt("Missing input argument."); + return gprhs[argno]; +} + +/****************************************************************************************************************/ +/* Returns pointer to static buffer (max 80 chars) holding a string in argument argno Global and error tolerant */ +const char *my_mexInputOptionString(const int argno) +{ + static char buff[80+1]; + buff[0]=0; + if(my_mexIsInputArgOK(argno)) + if(mxIsChar(my_mexInputArg(argno))) + mxGetString(my_mexInputArg(argno),buff,80); + return buff; +} + +/****************************************************************************************************************/ +/* Returns pointer to static buffer (max 80 chars) holding the first string with non numeric,nonempty contents */ +const char *my_mexFindInputString(int argno) +{ + const char *str; + static char buff[1]; + buff[0]=0; + while(my_mexIsInputArgOK(argno)){ + str=my_mexInputOptionString(argno); + if(!isdigit(str[0]) && str[0]!=0 ) + return str; + argno++; + } + return buff; +} + +/*********************************************************************/ +/* Returns true if if finds option opt at argument argno or later */ +int my_mexFindInputOption(int argno,const char *opt) +{ + char buff[80+1]; + while(my_mexIsInputArgOK(argno)) + { + buff[0]=0; + mxGetString(my_mexInputArg(argno),buff,80); + if(myoptstrcmp(buff,opt)==0) + return 1; + argno++; + } + return 0; +} + +/***********************************************************************************************************/ +/* Returns specified input arguments cell as scalar. Global and error tolerant replacement for mxGetScalar */ +double my_mexInputCell(const int argno,int cell_no) +{ + if(!mxIsDouble(my_mexInputArg(argno))) + mexErrMsgTxt("Argument has wrong datatype."); + if(cell_no>=mxGetNumberOfElements(my_mexInputArg(argno))) + mexErrMsgTxt("Argument has wrong number of cells"); + return mxGetPr(my_mexInputArg(argno))[cell_no]; +} + +/******************************************************************************************************/ +/* Returns specified input argument as scalar or a scalar product of its elements. */ +/* Global and error tolerant replacement for mxGetScalar */ +int my_mexInputSize(const int argno) +{ + if(!my_mexIsInputArgOK(argno)) + return DEFAULT_INPUT_SIZE; + if(mxIsChar(my_mexInputArg(argno))){ + const int ch=(my_mexInputOptionString(argno)[0]); + if(!isdigit(ch)) + return DEFAULT_INPUT_SIZE; + else + return atoi(my_mexInputOptionString(argno)); + } + if(mxGetNumberOfElements(my_mexInputArg(argno))>1){ + int val=1,n=0,el=mxGetNumberOfElements(my_mexInputArg(argno)); + for(n=0;npos+len*si); + + if(id==mxCHAR_CLASS){ + mxChar *ptr = (mxChar *)mxGetPr(gprhs[argno]); + int a; + for(a=0;aptr[buff->pos++]=(char)(unsigned char)ptr[a]; + }else{ + char *ptr = (char *)mxGetPr(gprhs[argno]); + byteswapcopy(&buff->ptr[buff->pos],ptr,len,si,swap); + buff->pos+=(len*si); + } + return len; +} + +/*******************************************************************************/ +/* Puts double scalar in matlab variable in the array of return argument for mex*/ +void my_mexReturnValue(double val) +{ + if((gret_args>gnlhs) && (gret_args>1)) + return; + gplhs[gret_args]=mxCreateDoubleMatrix(1,1,mxREAL); + if(gplhs[gret_args]==NULL) + mexErrMsgTxt("Matrix creation error! Lack of memory?"); + else + { + *mxGetPr(gplhs[gret_args])=val; + gret_args++; + } +// mexPrintf("DEBUG MEX RETURN VALUE:%g\n",val); // DEBUG +} + +/*******************************************************************************/ +/* Puts double matrix in matlab variable in the array of return argument for mex*/ +void my_mexReturnMatrix(int rows, int cols, double *vals) +{ + double *pr; + if((gret_args>gnlhs) && (gret_args>1)) + return; + gplhs[gret_args] = mxCreateDoubleMatrix( rows, cols, mxREAL); + if( gplhs[gret_args] == NULL) + mexErrMsgTxt("Matrix creation error"); + pr = (double *)mxGetPr(gplhs[gret_args]); + memcpy(pr,vals,rows*cols*sizeof(double)); + gret_args++; +} + +/********************************************************************************/ +/* Puts string as matlab char char variable in array of return argument for mex */ +void my_mexReturnString(const char *str) +{ + if(gret_args>gnlhs && gret_args>1) + return; + gplhs[gret_args]=mxCreateString(str); + if(gplhs[gret_args]==NULL) + mexErrMsgTxt("String creation error! Lack of memory?"); + gret_args++; +} + +/******************************************************************************/ +/* Puts data from buffer into next MATLAB return Array */ +void my_mexReturnArrayFromBuff(const int argno,io_buff *buff,const int line) +{ + const int maxelements=my_mexInputSize(argno); + const mxClassID id=str2classid(my_mexInputOptionString(argno+1)); + mwSize dims[20]={0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 }; + const int si=classid2size(id); + int returnelements= ( (buff->pos/si)< maxelements )?(buff->pos/si):maxelements; + int deleteelements=returnelements; + int swap=2; + mwSize return_no_dims= my_mexIsInputArgOK(argno) && !mxIsChar(my_mexInputArg(argno))?mxGetNumberOfElements(my_mexInputArg(argno)):1; + + if(my_mexFindInputOption(argno+1,"NATIVE")) swap=0; + if(my_mexFindInputOption(argno+1,"SWAP")) swap=1; + if(my_mexFindInputOption(argno+1,"NETWORK")) swap=2; + if(my_mexFindInputOption(argno+1,"INTEL")) swap=3; + if(return_no_dims>20) + mexErrMsgTxt("To many dimentions to return."); + debug_view_con_status("GET_ARRAY"); + if(line){ + int n=-7; + if(id!=mxCHAR_CLASS && return_no_dims) + mexErrMsgTxt("'READLINE' works only with datatype char and non fixed blocksize"); + for(n=0;nptr[n]=='\n') + break; + if(n==maxelements) // If no new-line found inside limit... + deleteelements=returnelements=maxelements; // ...return first part of splited line. + else if(n==returnelements) // If new-line not recived inside limit... + deleteelements=returnelements=0; // ...return empty string, and delete nothing. + else if(n>0 && buff->ptr[n-1]=='\r') // If(*3) new-line, return line of char but not nl chars. + deleteelements=2+(returnelements=n-1); + else + deleteelements=1+(returnelements=n); + return_no_dims=1; + } + if(return_no_dims>1){ // If shape of return argument is specified..... + if(returnelements==maxelements){ // ...then only accept correct shape. + int n; + for(n=0;n0){ // else... Just return row of available elements + dims[0]=1; + dims[1]=returnelements; + return_no_dims=2; + } + if(! (gret_args>gnlhs && gret_args>1) ){ + /* Create a 2-Dimensional character mxArray.*/ + if( dims[0]==0) + gplhs[gret_args] = mxCreateNumericArray(0,dims,id,mxREAL); + else + gplhs[gret_args] = mxCreateNumericArray(return_no_dims,dims,id,mxREAL); + if(gplhs[gret_args] == NULL) + mexErrMsgTxt("Could not create return array."); + if(dims[0]!=0){ + if(id==mxCHAR_CLASS){ + int i; + mxChar *p=(mxChar *)mxGetPr(gplhs[gret_args]); + for(i=0;iptr[i]; + }else{ + char *p=(char *)mxGetPr(gplhs[gret_args]); + byteswapcopy(p,buff->ptr,returnelements,si,swap); + } + } + gret_args++; + } + // debug_view_con_status("GET_ARRAY NÄSTAN KLAR"); + // Delete from read buffer if not "VIEW" option and dims filled + if(my_mexFindInputOption(argno+1,"VIEW")==0 && deleteelements>0 ){ + buff->pos-=deleteelements*si; + memmove(buff->ptr,&buff->ptr[deleteelements*si],buff->pos); + newbuffsize(buff,buff->pos); + } + // mexPrintf("DEBUG MEX RETURN ARRAY OF:%d\n",returnelements); // DEBUG + + // fprintf(stderr,"DIMS:[%d %d] DEL:%d RET:%d SI:%d POS:%d LEN:%d PTR:%08X\n", + // dims[0],dims[1],deleteelements,returnelements,si,buff->pos,buff->len,buff->ptr); +} + + +/**********************************************************************/ +int ipv4_lookup(const char *hostname,int port) +{ + struct in_addr addr; /* my address information */ + /* Try IP address */ + addr.s_addr=inet_addr(hostname); + if (addr.s_addr==INADDR_NONE){ + /*Can't resolve host string as dot notation IP number... + try lookup IP from hostname */ + struct hostent *he; + // fprintf(stderr,"Trying nameserverlookup:%s\n",hostname); + he=gethostbyname(hostname); + if(he==NULL){ + mexPrintf("\nUNKNOWN HOST:%s\n",hostname); + return -1; /* Can not lookup hostname */ + } + addr = *((struct in_addr *)he->h_addr); + } + con[con_index].remote_addr.sin_family=AF_INET; + con[con_index].remote_addr.sin_port=htons(port); + con[con_index].remote_addr.sin_addr=addr; + memset(&con[con_index].remote_addr.sin_zero, 0,8); + return 0; +} + + +/**********************************************************************/ +/* Writes from specified position (pointer) in buffer of spec. length */ +int writedata() +{ + const double timeoutat=my_now()+con[con_index].writetimeout; + int len=con[con_index].write.pos; + const char *ptr=con[con_index].write.ptr; + const int fid=con[con_index].fid; + int sentlen=0; + int retval=0; + int lastsize=1000000; + if(con[con_index].status65534 ) // TODO: Ta bort! + // len=65534; + while(sentlen0?retval:0; + sentlen+=lastsize; + /* if( retval==0){ + mexPrintf("\nREMOTE HOST DISCONNECTED\n"); + con[con_index].status=STATUS_NOCONNECT; + break; + }*/ + if(retval<0 && s_errno!=EWOULDBLOCK + // IFWINDOWS( && s_errno!=WSAECONNRESET ) // DEBUG: REMOVE THIS LINE? + ){ + con[con_index].status=STATUS_NOCONNECT; + perror( "sendto() / send()" ); + mexPrintf("\nREMOTE HOST DISCONNECTED\n"); + break; + } + if( !IS_STATUS_TCP_CONNECTED(con[con_index].status) && sentlen>0 ) + break; + if(timeoutat<=my_now()) + break; + } + con[con_index].write.pos-=sentlen; + memmove(con[con_index].write.ptr, &con[con_index].write.ptr[sentlen], con[con_index].write.pos); + newbuffsize(&con[con_index].write,con[con_index].write.pos); + return sentlen; +} + +/********************************************************************/ +/* Init current record with values */ +void init_con(int fid,int status) +{ + memset(&con[con_index],0,sizeof(con_info)); + con[con_index].fid=fid; + con[con_index].status=status; + con[con_index].writetimeout=DEFAULT_WRITETIMEOUT; + con[con_index].readtimeout=DEFAULT_READTIMEOUT; +} + +/********************************************************************/ +/* Close con struct */ +void close_con() +{ + if(con[con_index].fid>=0) + close(con[con_index].fid); + else + mexWarnMsgTxt("Closing already closed connection!"); + newbuffsize(&con[con_index].write,-1); + newbuffsize(&con[con_index].read,-1); + init_con(-1,STATUS_FREE); +} + +/******************************************************************* */ +/* Function to close all still open tcpip connections */ +int closeall(void) +{ + int flag=0; + for(con_index=0;con_index=0) { /* Already closed?? */ + close_con(); + flag=1; + } + return flag; +} + +/****************************************************************************/ +/* This function is called on unloading of mex-file */ +void CleanUpMex(void) +{ + if(closeall()) /* close all still open connections...*/ + mexWarnMsgTxt("Unloading mex file. Unclosed tcp/udp/ip connections will be closed!"); + IFWINDOWS( WSACleanup(); ); +} + +/********************************************************************/ +/* Read to fill input buffer with specified length from UDP or TCP network*/ +int read2buff(const int len,int newline,int noblock) +{ + const double timeoutat=my_now()+con[con_index].readtimeout; + int retval=-1; + + if(len0){ + if(IS_STATUS_CONNECTED(con[con_index].status)) + retval=recv(con[con_index].fid,&con[con_index].read.ptr[con[con_index].read.pos],readlen ,MSG_NOSIGNAL); + else{ + struct sockaddr_in my_addr; + int fromlen=sizeof(my_addr); + + // Copy 0.0.0.0 adress and 0 port to remote_addr as init-value. + memset(&my_addr,0,sizeof(my_addr)); + con[con_index].remote_addr.sin_addr = my_addr.sin_addr; + con[con_index].remote_addr.sin_port = my_addr.sin_port; + retval=recvfrom(con[con_index].fid,&con[con_index].read.ptr[con[con_index].read.pos], + readlen,MSG_NOSIGNAL,(struct sockaddr *)&my_addr, &fromlen); + if (retval>0){ + con[con_index].remote_addr.sin_addr = my_addr.sin_addr; + con[con_index].remote_addr.sin_port = htons((unsigned short int)ntohs(my_addr.sin_port)); + } + } + if( retval==0){ + mexPrintf("\nREMOTE HOST DISCONNECTED\n"); + con[con_index].status=STATUS_NOCONNECT; + break; + } + if(retval<0 && s_errno!=EWOULDBLOCK + // IFWINDOWS( && s_errno!=WSAECONNRESET )// DEBUG: REMOVE THIS LINE? + ) { + con[con_index].status=STATUS_NOCONNECT; + perror( "recvfrom() or recv()" ); + break; + } + } + // fprintf(stderr,"RET:%d/%d ",retval,s_errno); + readlen=retval>0?retval:0; + con[con_index].read.pos+=readlen; + if( !IS_STATUS_TCP_CONNECTED(con[con_index].status) && con[con_index].read.pos>0 ) + break; + if( con[con_index].read.pos>=len ) + break; + if(timeoutat<=my_now() || noblock) + break; + if(newline){ + int n; + for(n=0;n -1) + break; + if(timeoutat<=my_now()|| noblock) + return -1; + usleep(DEFAULT_USLEEP); + } + nonblockingsocket(new_fd); /* Non blocking read! */ + setsockopt(new_fd,SOL_SOCKET,SO_KEEPALIVE,(void *)1,0); /* realy needed? */ + con[con_index].fid=new_fd; + con[con_index].status=STATUS_TCP_SERVER; + return con_index; +} + +/*****************************************************************/ +/* Make a UDP socket be a "connected" UDP socket */ +int udp_connect(const char *hostname,int port) +{ + if(con[con_index].status < STATUS_UDP_CLIENT) + mexErrMsgTxt("Must pass UDP client or server handler!"); + if(ipv4_lookup(hostname,port)==-1) + return -1; + if(connect(con[con_index].fid,(struct sockaddr *)&con[con_index].remote_addr,sizeof(struct sockaddr)) == -1) + return -1; /*Can't connect to remote host. */ + if(con[con_index].status == STATUS_UDP_CLIENT) + con[con_index].status = STATUS_UDP_CLIENT_CONNECT; + else + con[con_index].status = STATUS_UDP_SERVER_CONNECT; + nonblockingsocket(con[con_index].fid); /* Non blocking read! */ + return con[con_index].status; +} + +/*****************************************************************/ +/* */ +/* ----Main function that is called from matlab-------- */ +/* */ +void mexFunction( + int nlhs, /* number of expected outputs */ + mxArray *plhs[], /* array of pointers to output arguments */ + int nrhs, /* number of inputs */ + const mxArray *prhs[] /* array of pointers to input arguments */ + ) +{ + char fun[80+1]; + /* Initialization on first call to the mex file */ + if(mex_call_counter==0) + { +#ifdef WIN32 + WORD wVersionRequested; + WSADATA wsaData; + int wsa_err; + wVersionRequested = MAKEWORD( 2, 0 ); + wsa_err = WSAStartup( wVersionRequested, &wsaData ); + if (wsa_err) + mexErrMsgTxt("Error starting WINSOCK32."); +#endif + Print_Start_Message(); + + mexAtExit(CleanUpMex); + /* Init all connecttions to to free */ + for(con_index=0;con_index=0){ + move_con(STATUS_FREE); + init_con(fd,STATUS_TCP_SOCKET); + my_mexReturnValue(con_index); + }else + my_mexReturnValue(-1); + return; + } + if(myoptstrcmp(fun,"UDPSOCKET")==0){ + const int fd=tcp_udp_socket((int)my_mexInputScalar(1), 1); + if(fd>=0){ + move_con(STATUS_FREE); + init_con(fd,STATUS_UDP_CLIENT); + my_mexReturnValue(con_index); + }else + my_mexReturnValue(-1); + return; + } + if(myoptstrcmp(fun,"DOCALLBACKS")==0){ + return; + } + } + /* Get connection handler and suppose that it is a connection assosiated function */ + /* Find given handel */ + // if(strncasecmp(fun,"DEF",3)!=0) + if(move_con((int)my_mexInputScalar(0))==0) + mexErrMsgTxt("Unknown connection handler"); + strncpy(fun,my_mexInputOptionString(1),80); + // mexPrintf("DEBUG MEX(2):[%d] %s\n",con_index,fun); // DEBUG + debug_view_con_status("CON_MOVED!!"); + + if(myoptstrcmp(fun,"CLOSE")==0){ + close_con(); + return; + } + if(myoptstrcmp(fun,"TCPLISTEN")==0){ + if(con[con_index].status!=STATUS_TCP_SOCKET) + mexErrMsgTxt("Invalid socket for LISTEN, Already open, or UDP?..."); + my_mexReturnValue(tcpiplisten(my_mexFindInputOption(2,"noblock"))); + return; + } + /* MATLAB called with status = UDP_CONNECT(fid, ip, port) */ + if(myoptstrcmp(fun,"UDPCONNECT")==0){ + const int port=(int)my_mexInputScalar(3); + const char *hostname=my_mexInputOptionString(2); + my_mexReturnValue(udp_connect(hostname,port)); + return; + } + if(myoptstrcmp(fun,"WRITE")==0){ + my_mexInputArray2Buff(2,&con[con_index].write); + if(IS_STATUS_TCP_CONNECTED(con[con_index].status)) + writedata(); + return; + } + if(myoptstrcmp(fun,"PRINTF")==0){ + mxArray *plhs[1]={NULL}; + if(gnrhs<3) return; + mexCallMATLAB(1,plhs, gnrhs-2, (mxArray **)&(gprhs[2]),"sprintf"); + gprhs=(const mxArray **)plhs; gnrhs=1; // HACK: Move return arg from sprintf to input arg of this mex. + my_mexInputArray2Buff(0,&con[con_index].write); + if(IS_STATUS_TCP_CONNECTED(con[con_index].status)) + writedata(); + return; + } + if(myoptstrcmp(fun,"READ")==0){ + if(IS_STATUS_TCP_CONNECTED(con[con_index].status)) + readtype2buff( (int)my_mexInputSize(2),str2classid(my_mexFindInputString(2)),0,my_mexFindInputOption(2,"noblock")); + my_mexReturnArrayFromBuff(2,&con[con_index].read,0); + return; + } + if(myoptstrcmp(fun,"READLINE")==0){ + // mexPrintf("DEBUG: READLINE....\n"); + if(IS_STATUS_TCP_CONNECTED(con[con_index].status)) + read2buff(my_mexInputSize(2),1,my_mexFindInputOption(2,"noblock")); + my_mexReturnArrayFromBuff(2,&con[con_index].read,1); + // mexPrintf("DEBUG: READLINE END\n"); + return; + } + if(myoptstrcmp(fun,"READTOFILE")==0){ + FILE *f=NULL; + const int blocklen=my_mexInputSize(2+1); + int readlen=blocklen; + int writelen=0; + if(IS_STATUS_TCP_CONNECTED(con[con_index].status)) + readlen= read2buff(blocklen,0,(int)my_mexFindInputOption(2+1,"noblock")); + if(readlen>0) + f=fopen(my_mexInputOptionString(2),(int)my_mexFindInputOption(2+1,"append")?"ab":"wb"); + if(f){ + writelen=fwrite(con[con_index].read.ptr,1,readlen,f); + fclose(f); + } + // Delete from read buffer if not "VIEW" option and dims filled + if(my_mexFindInputOption(2+1,"VIEW")==0 ){ + con[con_index].read.pos-=writelen; + memmove(con[con_index].read.ptr,&con[con_index].read.ptr[writelen],con[con_index].read.pos); + newbuffsize(&con[con_index].read,con[con_index].read.pos); + } + my_mexReturnValue(writelen); + return; + } + if(myoptstrcmp(fun,"WRITEFROMFILE")==0){ + int len=1024*1024*1024;int start=0; + FILE *f=fopen(my_mexInputOptionString(2),"rb"); + if(f==NULL) + my_mexReturnValue(-1); + if(my_mexIsInputArgOK(2+1)) + start=(int)my_mexInputScalar(2+1); + if(my_mexIsInputArgOK(2+2)) + len=(int)my_mexInputScalar(2+2); + else{ + fseek(f,0,SEEK_END); + len=ftell(f)-start; + } + fseek(f,start,SEEK_SET); + newbuffsize(&con[con_index].write,con[con_index].write.pos+len); + len=fread(&con[con_index].write.ptr[con[con_index].write.pos],1,len,f); + con[con_index].write.pos+=len; + fclose(f); + if(IS_STATUS_TCP_CONNECTED(con[con_index].status)) + writedata(); + if(len<0) + my_mexReturnValue(-1); + else + my_mexReturnValue(len); + return; + } + if(myoptstrcmp(fun,"READPACKET")==0){ + con[con_index].read.pos=0; + my_mexReturnValue(readtype2buff(my_mexInputSize(2),str2classid(my_mexInputOptionString(2+1)),0, + my_mexFindInputOption(2+1,"noblock"))); + return; + } + if(myoptstrcmp(fun,"WRITEPACKET")==0){ + if(IS_STATUS_UDP_NO_CON(con[con_index].status)) + ipv4_lookup(my_mexInputOptionString(2),my_mexInputScalar(3)); + my_mexReturnValue(writedata()); + con[con_index].write.pos=0; + return; + } + if(myoptstrcmp(fun,"STATUS")==0){ + my_mexReturnValue(con[con_index].status); + return; + } + if(myoptstrcmp(fun,"GETHOST")==0){ + int n; + double ip_bytes[4] = {0, 0, 0, 0}; + const unsigned char *ipnr=(const unsigned char *)&con[con_index].remote_addr.sin_addr; + for(n=0;n<4;n++) + ip_bytes[n] = (double)ipnr[n]; + my_mexReturnMatrix(1,4,ip_bytes); + my_mexReturnValue((int)ntohs(con[con_index].remote_addr.sin_port)); + return; + } + if(myoptstrcmp(fun,"SETCALLBACK")==0){ + strncpy(con[con_index].callback, my_mexInputOptionString(2), CBNAMELEN); + return; + } + if(myoptstrcmp(fun,"GETCALLBACK")==0){ + my_mexReturnString(con[con_index].callback); + return; + } + if(myoptstrcmp(fun,"SETWRITETIMEOUT")==0){ + con[con_index].writetimeout=my_mexInputScalar(2); + return; + } + if(myoptstrcmp(fun,"SETREADTIMEOUT")==0){ + con[con_index].readtimeout=my_mexInputScalar(2); + return; + } + if(myoptstrcmp(fun,"debug")==0){ + mexPrintf(" FID:%d\n",con[con_index].fid); + mexPrintf(" STATUS:%d\n",con[con_index].status); + mexPrintf("WRITE TO:%g\n",con[con_index].writetimeout); + mexPrintf("WRITE PTR:%x\n",(int)con[con_index].write.ptr); + mexPrintf("WRITE POS:%d\n",con[con_index].write.pos); + mexPrintf("WRITE LEN:%d\n",con[con_index].write.len); + mexPrintf("READ TO:%g\n",con[con_index].readtimeout); + mexPrintf("READ PTR:%x\n",(int)con[con_index].read.ptr); + mexPrintf("READ POS:%d\n",con[con_index].read.pos); + mexPrintf("READ LEN:%d\n",con[con_index].read.len); + return; + } + mexErrMsgTxt("Unknown 'function name' in argument."); +} diff --git a/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.m b/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.m new file mode 100644 index 0000000000..419b3ad0b5 --- /dev/null +++ b/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.m @@ -0,0 +1,234 @@ +% PNET - IO-function for TCP and UDP comunation in matlab. +% +% +% This function can be called with different options/commands to operate on +% tcp/udp/ip connection in matlab. It supports data transfer with +% different data types and byte orders. The function is implemented as an +% MEX-file that needs to be +% +% General syntax +% ============== +% +% pnet('command',....) or pnet command .... +% +% ppet(con,'command',....) or pnet con command .... +% +% ...where 'command' is a string specifying what to do. "con" is an +% connection handler holding a number that refers to an already open +% connection/socket. In the cases where "con" is specified before +% 'command' is the commands associated to operate on that connection/ +% socket. Connection handler number (and some other numbers like size +% values) can be specified as either a scalar value or a string +% containing the scalar number. +% +% Commands for TCP connections +% ============================ +% +% con=pnet('tcpconnect','hostname',port) +% +% Creates tcp/ip connection to the specified 'hostname' and port. On error +% it returns -1, on success it returns a conection handler as an integer +% number >=0. This function call is used to act as a "tcp-client". +% This function is alway nonblocking unless their is some troubles with +% namelookup that can block interpretation for a while. +% +% sockcon=pnet('tcpsocket',port) +% +% Creates a local tcpsocket and bind port-number "port" to it. On fail +% it rerurns -1, on success it returns a connection handler. To fetch +% remote connection connecting to this socket use pnet(sockcon,'tcplisten') +% +% con=pnet(sockcon,'tcplisten', ['noblock'] ) +% +% If some remote tcp-connection has connected to the socket "sockcon" this +% functions returns a handler to that tcp connection. On non available +% remote connection or error it returns -1. Unless the option 'noblock' is +% specified or the readtimeout value (default to inf ) is reached it blocks +% until a remote connection is established. +% +% elements=pnet(con,'write', data [,swapping]) +% +% Writes all elements of the matlab array "data" to connection "con". +% Supported datatypes are: char, double, single, int8 int16, int32, +% uint8, uint16 and uint32. Arrays of datatype char is written as single +% bytes, all other datatypes are written as it matlabsize. By default +% the bytes are swapped to network byte order unless the swapping option +% is specified. Swapping options: +% 'native' no swapping use the computers native byte order. +% 'swap' allways swap byte order. +% 'network' uses network byte order (little endian) and it is default. +% 'intel' use intel CPUs byte order (big endian). +% This operation blocks until writetimeout (is by default inf) is reached +% or all elements are transfered. Returns number of elements successfull +% written. +% This command can also be used with UDP packets, se the UDP section. +% +% pnet(con,'printf', 'format',.....) +% +% Prints a formated string to the connection "con". SPRINTF is used to +% process format string and following arguments. Se help on SPRINTF for more +% information. It block until writetimeout and returns number of characters +% succesfull written. +% This command can also be used with UDP packets, se the UDP section. +% +% data=pnet(con,'read' [,size] [,datatype] [,swapping] [,'view'] [,'noblock']) +% +% Reads an array of elements from a connection. Unless option 'noblock' is +% used the operation blocks until timeout is reached (by default inf), the +% specified "size" is reached or the connection is disconnected by peer. +% Specified "size" (by default 65536) can be a scalar or a vector of +% specifying dimentions length for the multidimentional array to read. +% If size is a scalar i.e. [10] it return 0 to 10 elements in a rowvector +% depening on available elements. If size is a vector i.e. [1 10] or [5 5 5] +% it returns an array if all elements is available, if not, an empty array +% is returned. The datatype option is a string containing the name of the +% datatype, if not specified its by default 'char'. Supported datatypes is +% the same as for the 'write' command. The option named "swapping" is +% is the same for the 'read' command. The option 'view' gives an "preview" +% of whats available, all data is left in the read buffer. In combination +% with 'noblock' this is a powerfull command to check how much and whats +% available at the moment without blocking. +% This command can also be used with UDP packets, se the UDP section. +% +% str=pnet(con,'readline' [,limitsize] [,'view'] [,'noblock']) +% +% This commands works like 'read' but it reads a string of characters +% until the newline character (code=10) are reached. +% It returns the string without the newline character (or if exist just +% before, the carage return character code=13 ). If the character line +% is longer then the "limitsize" the line is splited at that length. +% The default value for limitsize is 65536. +% The function blocks unless a full line of characters are available or +% 'noblock' is specified until readtimeout is reached. The 'view' +% option also leaves the returned characters in the read buffer. +% This command can also be used with UDP packets, se the UDP section. +% +% ret=pnet(con,'readtofile','filename'[,bytes][,'view'][,'noblock'][,'append']) +% +% Reads data of specified number of "bytes" to a file 'filename'. It +% returns successful number of bytes moved from the connection to the file. +% If the option string 'append' is specified the data will be appended +% th the end of the file, otherwise the file will be overwritten. +% 'view', 'noblock' and timeout behaves as earlier described for read +% operations. +% This command can also be used with UDP packets, se the UDP section. +% +% ret=pnet(con,'writefromfile','filename'[[,start] ,len]) +% +% Read data from a file and write it on the connection. All of the +% file will be transmitted of not "start" and "len" specifies a segment. +% The function returns -1 on fail. +% This command can also be used with UDP packets, se the UDP section. +% +% stat=pnet(con,'status') +% +% This returns a number telling about the status of a connection/socket. +% It is a different number for each type of connection or socket se +% #define's in top of pnet.c. The most important status is when +% peer has disconnect the status value is 0 else it is >0. +% This command can also be used with UDP packets, se the UDP section. +% +% stat=pnet(con,'setreadtimeout',sec) +% +% The value "sec" specifies how long read and listen commands blocks before +% it timeouts. The unit is seconds specified as a floting point which means +% that i.e. 0.1 can be specified for a maximum of 0.1 seconds blocking. +% Setting readtimeout to 0 is the same as adding the 'noblock' option to +% all followinging 'read' or 'listen' calls. +% This command can also be used with UDP packets, se the UDP section. +% +% stat=pnet(con,'setwritetimeout',sec) +% +% The value "sec" specifies how long the 'write' commands blocks before +% it timeouts. The unit is seconds specified as a floting point which means +% that i.e. 0.1 can be specified for a maximum of 0.1 seconds blocking. +% This command can also be used with UDP packets, se the UDP section. +% +% [ip,port]=pnet(con,'gethost') +% +% This command call returns ipnumber and port number for the remote host +% that is (latest) associated with the connection/socket. After 'tcplisten' +% you can get the the clients ip and port numbers. After a 'tcpconnect' +% you can get the ip and port that you connected to. +% For UDP sockets this gives remote ip and and port for the latest operation +% of 'readpacket', 'writepacket' (if not connected) or 'udpconnect'. +% +% pnet(con,'close') +% +% Closes a tcpconnection, tcpsocket or udpsocket. This comand must be called +% after ending use of any socket or connection even, if its detected that the +% connection is broken from the remote host side. +% This command should also be used with UDP sockets, se the UDP section. +% +% pnet('closeall') +% +% Closes all pnet connections/sockets used in this matlab session. +% +% UDP packets +% =========== +% +% With PNET it's possible send and receive UDP packets. Same read/write +% commands can be used as for with TCP connection with the difference +% that the operation is alway nonblocking and data is stored in the +% read/write buffer in memory. With pnet(sock,'writepacket'...) can the +% created UDP packet in the write buffer be sent. And with +% pnet(sock,'readpacket') a new packet can be recived before reading its +% contents with read commands. The limitation is how big UDP packets +% your network can transmitt. But about 65500 bytes is maximum. +% +% sock=pnet('udpsocket',port); +% +% Creates a UDP socket and binds it to an UDP port. On this socket can you +% recive UDP packets destinated to this UDP port, and send UDP packets with +% this sockat as source adress. Retruns -1 on fail or a handler >=0 on +% success. In this sockets write buffer you can create a UDP packet that +% is later sent with the 'writepacket' command. +% +% pnet(sock,'udpconnect','hostname',port); +% +% With this command you can connect a destination host and port to the the +% UDP socket causing that the 'writepacket' commands should not have any +% 'hostname' and port arguments supplied. +% +% pnet(sock,'writepacket' [,'hostname',port]); +% +% Sends contents of the sockets write buffer as a UDP packet. If the UDP +% socket is not connected 'hostname' and port must be supplied, if connected +% the arguments is ignored. +% +% size=pnet(sock,'readpacket'[,maxsize][,'noblock']); +% +% Reads next incoming UDP packet on UDP socket "sock". Unless 'noblock' +% is supplied as option it block until readtimeout or next UDP packet is +% received. The optional argument "maxsize" limits the size of the packet. +% The packet is stored in the sockets read buffer and can then be readed +% from the buffer with same commands as for TCP connections. When reciving +% a new packet old non used data from the last packet is discarded. +% +% General alternative syntax +% ========================== +% +% pnet 1 write Hello_World +% +% is the same as +% +% pnet(1,'write','Hello_World') +% +% Numbers like connection handlers and port-numbers can be specified +% as strings in most cases. This syntax should generaly work for all +% variants of calls and is usefull and easy to type when experimenting +% interactively with tcp connection and udp packets from the matlab +% prompt. +% +% +% SE ALSO: PNET_REMOTE, PNET_PUTVAR PNET_GETVAR, WEBGET_DEMO, POPMAIL_DEMO +% UDP_PLOTTER_DEMO, UDP_SEND_DEMO, WEBSERVER_DEMO +% +% +% GOOD LUCK and HAVE FUN! :-) +% +% Peter Rydesäter, +% Mitthögskolan(Mid Sweden University) campus Östersund, SWEDEN +% + +error('You need to compile pnet.c to a mex-file for your platform. Read the header of pnet.c'); \ No newline at end of file diff --git a/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.mexw64 b/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/pnet.mexw64 new file mode 100644 index 0000000000000000000000000000000000000000..ac82ab90dbfe79d473a6520a09fbf143da4c6ec2 GIT binary patch literal 30720 zcmeHw3wTu3wf~+Z6G9%G02vG@FhHmY&p?7EghwWsfipOHmi- zU)>+mKIF%@2i_yw5^g_^bl2LaSG4i)M=R9y6DyAL^iv%Ef1FRR=tTN)gdGUmhdh1z zV+i$YpWylWwLe~Qkf)#IVM&dBE%Eqk5*1q*tGX|m)f_o`X8@<4O*F(ds05U~| zdI}LH@^~Y}SK|?kMRQOvWc>g@sSj4^SOi-IRJBkbxH_#uioJ|AqUZ^PM1q}Q>_uYK z%2+xzRN(1hjC7b=&)5wC*tdkMke|*gs%5SMDb)9`Ju^IxjUHqsS@EGNlkAWq^f5BF zYKE(-(o@OU)^W&Lg%?0Zx(Ru5QN0-|8rwM=8I5>}H|iAnCr$-eId2%_Pqt*#T(h=*yOMKVk4S8}I%L_^VuZ)VmbE)$E=paq4 zo_Nup@Y@xP$+dGC6Me6zipu2pTNyhR@({l7Qk3Ub-=%18jNcSNc4Z+8bo{4tftnDaiY|v7_Kj7tdAr(avM1OA{!`n{c0+(uDe0>>))e7 zk=>#crx-Q>7rAE2?c{?>L+S`YDp8Tf14&rc%K53dsJXNJS#CzC#A z`jm;y=2=yEYemhX_HXNqnx)|BG|v(#B#apPBtmH8o$adBVsmXuqS)+7NnU1JYFb8u zXIvm9|{`sGvt2Y}Y3?Q3-P7G>mmO5cAiF5JJZx>^{&gD1qtHBDtV zwF)~QCKZ#mKEY6h2J%3NL|-DsXDEhMMI1OCz$ML@8Cph;Vpz;G3`xk~syNbs{G5zd zNSYmG_UGy-LTbn+HDr?-vPliuq=sy$A-lFSDq9skTNA!E8^YISCn^V<4X@Op`Uibq zRtXQH?DY)&myw9L>45a++GfI zY@qf?7yZ*cZpNyc&1uQP%WtauI0b-aj>%|kUODpys&y9RooS?cr>nHp{#(9unW@ZF z&KuPKTuS3*$hiGnBgTg)>F=#Ykny_M+(fg4r2luMZT{(zU}(v>V3kgrqyd}sk@UIg zHL5+DvFRZ+qhE{={beb+ilGw1Yoqr*67<=dK+vC1f<_C(M}4g*JZ_Z^?W>|ru%Gu1 z*1t{k=Qf~Gh2goo@b1RD7cZqx;O)WNZ*JbW3vajBT>LoR-J-8o=k1jAF{r7zdCoWM zuykl`o|E=t^iBO2NZFbvCsAU4G`?c<*o#kb#1qJBQnry9C@(|hlsU+i#-2tlhNb)> zk~aV3Bf#3xD(v_O>M>`}X{WL~=e!8$)?BFTmmE7rz7N{boubmwxUj+-Cyb{QqMiZarRaGT-uPX@ON(^K zo>$@di*Nt~?>W#B4hTf@C!D0``F+p@vAK_x-ZEi)uB!HB@uYw7FGK{|{d@V(4DwI8 zivKUr45D8XUQhhZ8vg;TfgpU4|5HOX{*NMZ4gB|jP(Xf8)3Z0@u$+zc+j(JHm%Qpa z8pvMi$Qi+5|%Ul!*TQvbii zY4tyc$TigeGb{?V`kzHKr#rO$p26S~(q2qyAhQ_mHc8Ly4^q3;Ij;0mil z45~BOfnuw74UQ-3Kh7ZkDwY3>!T#d{|3SVM;v48cSt{RP``r`hKb~vrKc9&~`4J75 z|8hwP|3k>$2V>0pZwto_(f^wP{)euOzca|c>MH*Ch4Qx$e=>f&{jcPISAc)zwekOK zaZr9l!{r|n%Ks3u_W_{F&v8TKzc;{t)3xz;2KiTA#s3+sRDbWp za{~OQT^s+;Fe3!yM>Jgi`$G92LiRowB(?u@+z|Pb1N?<+qVJST+ph{IQT>od30~-_GR?s^CLJbJ{)62dAKy3qn+I5ZQw& z_zmF>uAd?~e^lhlYtz3o$h?XZ44r?Mgfh2;GS5<(mk+L=ehRjH{q&>1#b0QOK?e$( zfIl@2O8*B$(E;`Zr9W*8k^XgL^PL7wKreG#FDjs}-z)+C^FsLt_zlkg0f4rmrWHV4 zumY>q3cP^T(vSkIk$#nix}|FC56QnuhuUNulW&=VP_C}-ZKJ~MmbuJb;~-WL}>s!oa-wxjG0dhBQc#MEM6;X!mx1qbTQvM1AZn zs6i7!Isj2+{x|59mgM`1f}EA2ioNj!L>9O(9RdH!x5;~MWw^XCB<~2w2-)XRJX)3a zb>RI&<&FL;^8RcTq?5@9@ccPN>HPpP^b!l$lcMu{Thc_Gumfums^Oog%T|4d;)YQo z1_U1(9$KZ_6Nd9Lr{Q|*mp=s6CH8q!h1CA@dBSqf)Wlb)E1INt;G@Yxw`ewe1b@5L z&Yfo%F=?VFow|9m;RxVn?(yLx=8rJY^5^JWV1GR(EBQYWmkd7zmS{f+pTMxyh^;%( zpmu8MxHS@6`ZJ1Q#yr5K0rdNAi{SF2qPL({)xyjU!MB6tX}aLu<}ZxJ_{bq*`eM-3 zhQ^5oQ924ris6sQ<5ae`iuN;=8TZp^39u}F(-6gQ z2$?qf{PXahTGt(K$ZMXb_CV5UaAb`)pdFTfgDin!4(N|}d^p_T82n&zxd3`C2cN zUn^Z5h@Va(6f{Jq{v}}3a1@*MKcj+n{SI){n0*5a4QAL)A05i`*77`bZV3j@C&$76 zEZqP5OBe#1C!o%6AqIC}9>+Qoj&%Y|UZYMAw^JGr{1wBp=g$Mnt?S``nu-WAQmCX9 zpDbUV$o){WvgeORj_|P7SRNA^YaG>HN*H(mO%QZN#gCRRp^$JO;mmTf+|5uidG*l# zm>%aG0Z?cXkbq;!*B;Y%F9yI*0K|B_4?SERk7tKKY0@!iK%R2F29vtwdT^Jz%+hg8 zD$-l>Yh!2_-9csT2l+h1Tc!tA8_F`lg(zj*Tg}t_2A0+ zgI9#ct6epc{|XB#89v9F8@xjMflK9P_L~%W7;#$$Zt4JdEe>S{(31P97@4AAYi$@0 z&fkY&P*ML3+h&$pGfrU^%_3FJp{5Fy6B$-VG12XF7)5JaD%mYu(`no4u2ZvqZ9`WhsUaIO0(=772#^6!#lOqG8o4 zRe~SfH73;mOY$6|+b>G(WvQ8w@5(P?l>iw(htI_(9VHQ= z$|ZK&l*}cOwkfGxsfwXmrEwHkuyM3d0O>s4mMNKvVTGEvhw_k-2Q9+U9Ot`)fvcw~ zw~d9q6=7!#64gTeMQH2-Nq!h(r8nXNH$rz)X}{r4G!i#gFlc5~6~BhqJcc22BS=86 z@@LltyK@GqDmZj@APY=dd9$n`4!i%tIS9OdgIzWH=U6l--ia!cdJyJK$1Qp*MhnQ$NyrYqJJ7_lHnqg|ILWHPtg9x{|%tvtaHm*aQ_4rUA~BE8u1B4z7KJJ zG!EKSXFBgprt?EO4BmcjH<6U|g&@Jt40ojL;!JvN(w8=W<|jz7?CB5ROTG3795-Pz z5`0C~fo0U-IwXFW>;Ws`fQ^nfu`;vLdV1JwtW?OuGoTnE5YHL#<~1&09Zo1wvQ)I6P5su0>k8Vq?LBeCQ)c4%xRKr zdNl&nXOiAM*@=d!?gtHZo{IV(12xA1?C}vTQ_# zv@E`?Gbs?GjJ(=z&iF)SalAF>^DQ6u*=_csc$2?Cu|*1)MK|O%eX`YtHKSSj59`#!Hve*D zK!F{Wrn6hGzr~+~<4g40mtsYKi2_3C^{v*N*SCC95P8h%`;*T5cHc0Y9jE0dtkPlm z?a5e;SAgfrlw#=+op>*&1MyXXlX~u7K@aBlH|Rb?BEQQZ+D~VX?catLvY+Rgx7`GV zUbv1o*$IM6@!j%Xq<5$XVP?vI2kGpw`;g7cBopkQTIR_>nR_Xn)9<3wvzdhO6JBUX zpwJ&+?`6MQXicEdZ9I+399UIF^^*Wu+PVEz_9A<1HcEBqrxZZ#TfOLE6NpOl78*bE zcsE1chsd9f;`@QT?6E@wtk)9j5u8=RxvePVAN!xSz?J|DQj`-{nie(X z*Y5+a2J!2k8%(G*I{I@ac>b8v)Ndr7q}LL)Zr7tzreHAg ztKr>(?xgUFwP%l=8K}}jL^(^PJR(5(auQ!!xAJQ&Y7ri7DQ>5_(v_1y?+UT+0lVg} zO*sui-;c^ePR9}ibUDOwoy`s-f8Hd$Va7grn(QOv(QoowbW#@pnQ{rLPm9_y2_zUm z>DW1-d*;$dgxwRH@3|lE!+3vy_i4O8!@CFX%XnYI+llu$-gohy!TU$NpW(fT7Z;Z9 z8G=`k2Tp@EF-@bCMY8bzX_Blz7qTl8jUt84@r#j_c(@XiIEm8Z3MRZzD`@6wNgdLb8xH0w&FK9Z;FV20B5T*k`dbjDlt)s2dFj4A+y=7vb#mWF>_dIvp3z7Gx-Y(ZL;jspL-7;+TbJFLw`1F+|= z-RFQ@7I`C*A3htFDXn-5g@j5hQ!wK`&hZdJby?`SNf=HOQMN zgX+ISN0!5$@Nc{XHU}-hph-_?x(I$YsntyC6&~7$lT~ucQ<94vl9XMkO1Od6+2n@d3r#E>h>xf?HOCi=%0U3PoTCOxQS?7qgtaSm zH0s*$Pgtc~?R8-om zImc-}Kd#Q_ihcoD^iAOWU^=k&ID;N54~)gaM?aDB^gIt0z#`v}oQ^hIhdn5~9#fhw zZ2b;8Im%o#rLB)IurG=iRd>fe6gNprA5FQo(g}64RDQ@h4Mq3AX)pvT&g% zG1`3QJC`Nt|II=@vwH(3lQj5R;bGpYr!DA8?nfZ!))9FR?VzQEUjhle&Vv%#7PN+< zlKv6Okm9?8muji8lDH6B6eEHsO^WO)4nei?xNnC;=>`hw@J=}N%Xkj$4u_sq zp}z}<(j6jDct0H4qC!6ihd!f1d%~d)s?d+Zq3c!X*>LD875Z^FbcqU;!=aff^iSc? zaVqp&I5b9uei{xv55F*E>ko&%uR_m*^7i0;3-Ln;-@|Lb z`#D}8-eq_{1nv;@RW@3CbP-x4G6114N*_IBbPUCYj*g9sPZ&K+NE|+5WYTEED8R0x zjKA_E2iKYu)9z2#rX|ihAL}_bHz3S(tmzNUOgn z3*O|&<8l)Y!T5O{c)SXhxW-N{qa}7+95+vGwO~=c04ovD$QEOT2j7N*u<=|HS(crJ z^Qmmy#~qJG>&8-G$FrcnX}Dr=85x_OaU<&0lugFUuCD^&3h>|I~H0W({xIB_&X?)^N!#jhfp2@A=NWP0ZHt&n}#5?G+pq_2H6B6dstl8+5jhi zmYM2${SwKXl|}pK#(6QZ!j7AO&Zpb1EuU^zWjYUs+1WQ#3x`^D)f64WkH41KQRzYPsdeCyqXT}j`Zxzwwb3d(^e5U! z+4VK(S|sxzK{!rR=Hi?ZoQ0R+{+x#rSZGoAC2u>inmeYqQ!P!MoNKHTT0-4uFp~Y1 z?}TDNJuZ+BEt*BlS0c^tAI6Z!Wo61Lt8{y+Rays^k~@ng)ncpk2krJg{Cz}cI8Z^S z9RnkbPv0{pskQI~>)xQPh*`px?WpvQB+EDOT@W_4 zKcu-O_u@CSi3{1(U)le;H&E)u4WcO%Q5oqHof@HuqM#q`s?#Ot40m^Mdj*pzykWwQ z!)VaPg^08wat-&__JEQ`^rxJtXD`2G4DK&ZAnxBN28rVo@QYj9RL-|>ru6})jxeS{ zR~&Aj4-LOByD-QvQ|0#?ej^F|Yyp1Phwu|Z`RN1vzNR^L@RIf4;&*)PpnR_*it9nY z*=Ob5XU_*fj->HB0-M0)YvaZtaB2N->2q6j~&m7>_2miNlK$Y(d;uslf`_W+$m+v!bfxoN2 zJk4qGA45FKNuj@}^38uAT~RS?4PoX|nH6&$j}WtaP?H@yIX7J4J48P@fHu|JV#ve~ z66pT;A&Pn~V%)(_hR~a+a@?!_0*(K82c{yI%!Wv-(Tet#XwdFE+cJcL-?zYKvA%a& z=rE}7cnewbzOELm5m;XvExTCXe!5r5`hFc^z5??t{hkY^hGy7D;7tz9uvokYu3Ef; zUdW`+rK3%!JPCA2y_vhC2l^7Uv(vkfmIi!^;#rN~AXU>H8^z!yB)YN!H$Hxglrnce zT}$CqjZq+o<5ij>=HWHthgwlM_d*HniU>9f_#G6Edlk5r5ux8tB`AiINVU+M-j})` zn-Vm`4*;QiBblgdCVCU&S7Lb4N09|jL0}H}J&h&kaxJN`0ctD`b#`g%5BlMk_9HIZ zL>TegDD|gqxtJ67+zbl14@V16nP%U6;z9Cu8E$LLkl3kUp<$ld zX^ngbtAYtw6{u&ro;d8R6~ix4qHmlP(kDauRGO;A$TnnYQ|~Lt&$s|jW>J6S<)+q6 zP@oJDUx|2Uf!7B&kwE;wn26I&l=V^g8I(!hjdLklX1H(4`9^rKgfu=41)dKS=tOP6 zj%MFijhHoipbW$hQ~Wr=?fUH;_e4Wp+Lno#xOgxTS};${giv(xU?w(NnB-S-q?0(Z zw_(}9Zyrp{lp{cmS`HI7&5>G*VK26k=4^5b=ko3O%8=dSv16UO*oX+$iDph8(ymN) zp!t=_%lOyIzd8Inoqxyk?{NN&FbR+-!8TtPVD^wx|&vJjN)t@ns`#_Gs^d+&J!D~x4adW zrB5#xArM|_<+51u^B&053%3C)KzDkqjVF`Icw?+%%-{?~9WLt6VWsmn>2vJ$KLru` zy<8Ux%3eKV4|MN@hc5SJoo{~KTmXfpL-=;;??8eEuiOeG{B*8JJ`P(Ze+fGwPXGuW z9y+{04?BZE9tE3*oqL*mhl*}Q{sA?A59Rm6^mXcEK$I+3?ri0Oqw*=3%G@1_ccGjN zYe`pBd|3?k6mIG9$O6-3o7AzN3cx!gN|Cq)wgkjX%1K2(8G7Y9QqKqJU;;)2Ef4oK zbYV2z*}jiVv3v~QU8HBy3z^mQ+y^d6`v1(J3U5oG!^M@{(UD%!u5>l)k0C?89b$6L z7=81XW~0*Hn`I{?lVeGK9W>#ayZ~?pG2*}=<5cbg$K}b0UFg34J>MU6^4-9e+WVeS zE3ud=vFn&9VXw5@Xlu?*ZZ1aqh%t0li#p|6rGA{rN}o5K@(S4o5p~!`#);fs{ycau zbQ>&~4IVW@Pf&AgU>@j8QVchv`$^rf+39pb@*+w=Ytp;qP}`05Z7}PHp;-y&eQK6Z z(Rs5#^d1z;I7P)iC%fEq0liA@;3qBm>s7{{+X6T^uT4U)v^FUoy-$hs<__|l7Qz#L zCrN*X76YI^)W2MZHc0PF3g9Y+?}CV0i@xZL_b35RjQ!Onfin8ZpDQ4A}2 zvTOg)C`RMTcstIuiV23JfEX0Z+6TMBWINg$x4(w)V}Li{OG_vv{~LMZMeLcduhP#& zi>Z4oUn@qR{s<5t`y>K4>mQw^V&)?LIC47m^?(r9PW@WMXrOiKU0RH<9k64h!F3mv z?2OXUAPB;xgw5$h*cN3B0Cn(g-Vp$z;N4gf$@n833gpUCZQoK-U@kPF7;-Q(iPEnJ zKs7@lS0#5xN^dHLG|GXn*zi`RWT6V=xs>22q&sg=OF9~lfDM#L#m*LuW>gGc!V)Q+ zJ|$wyuc+xN?&KE|cxJgMol~1Y|N2Z2e`WSFXQuyfDq{GVg-7&ZRuKIK$+)Kj8lq%@ zufdXtc@Zi6s(Tj2-&W)P0;8J#Eu}3+6iXD_dW>QQ;u)4iF{4e~M{5y&+jbHX89`Q} zU~Yr@O*4tfN*IZYa7yZ@P!cVF2aZwkw+hgy5=GzqsaX0mZ?s}?gHg~DAA?@g=AeKw zc{MU%Q*d7e>0XB64X@%@#Bl{c3qeoDO)fM*Op5%m8d3iM0-vYkpTQJE(Gwh^6g3$w zhiZv2eR?sc%afGR+Aj*fN;nH6=lyiHYV-H%`Yvkog}hEJJ4Aj7_NZ^PT#7Wz=94No zYIbYi5cx4A_Ua&9Dwhq$e?IydjQ?XQy#OrNGgTxTo3uxcDkn*w}5c$p^ z(SS`2uFtdqdWnn~#%QnnI*cGj{wUv9I`439Iz;IWoOI!L3%moCr7Xu<5bIn%a%t;L z+i+@+irynAOKl==<3v1k{pTzVCz|&T0VcnrQrF9`a@3%l`?PfLUPM%%weXVuX%ucc z{0faV!Q8%6|1i?>dYD1E8EBdYlH@IFVkq=QHoWgo4`?UsgSMn`ei@1~>9ltZ9kARb z{~nEimP~DW4}U|zpRj-kk40ICPPJY{=>(qk%z&0Nss*S1!!aaEmx6;HeF6~B7e^tW zB!x(hN6?|~g}Ko2W`J*<1j8JR4`1tGdTeVcSOGVGw!ZQ?Tr6CV_1mL}VDi0{g2*G= zv*~Zuc<*S5g9WM1HYIyYY*P;kFPoA?|E zG_eq%SqAj5XcPUGe&JE|P?eb8M@+#j7j_F#^uBm#KE^Lb%CGTh{K=FP&=pS8NM*P# z68W$?5KEj}dduxO&x*O5;;)2R`Ca_FvVqPhL^> z$-h$eAUZJ34T-c)<$K-4jMj|9!ZT*6&64q+SvqRk-e2!=)S9+`zSvRkHA|Pp9g1}7&!no8ySbU4y$JjNn4}&v z1JH@QS71(Yb+8ptGE<=>V3yNG|Y_&1M#-^V<4Ab=vL$!)J_svt zECg(nHv_VZXSN43ROI*YOAZx=?Eh5_**UP z*242z7_(KSH%<$)w6IJI@6tjQi?R2$dYsb2KWkyqcLNw|h(!iHje-`ELjX@B%sUT9 zY9Xv8Ps3dEkOmc=MluW(4%b5LR_JM@)i{MP&^)AF0-i=J*LdjGLXQ@rbJNr4)Iv4D zO&YDf>#wMHt(LC30{+u0(&<}NN=aHMYTQ}O(ZUWbq&rlhPo9>ZtA*)WxI_y} zv~YzM2FmWz()VfM6IbLvptZ|ZEv(nVJGJnqS{R_0r=^p$aA1>~^RX7buZ3@F;Y(Wh ztQJ10g%4_B`W5uWrD~f7!p7xl`pPg+pZ{tYJO3a1#M+#dRgNlSL%qXeEU+w}UR_h` zFjhNVM$cM@(PM9z>8)y*S<^7x<8;=pc5XE0JL?*NQf16F7F2FB&YokOojyC=I4g5* zM%LWStk|Uvm%GMUZ#2%Hkv?M%g7ox^>FL?iXWbN=?`+uQs#&wvV@%CYGZs5M4wtcH zQ_%IS z-BIs$Of$M2Mx-e|!?V%DD_`xctqlN;_$!b#?isPSIlab8mjlFWonU43IE|@Qo9Zj; zYV4J@o6>+@zYbF4FGzA7Y^d?9MbY}{)h>s_Xs5p$X^f3E8jWi`o`$(IXKvWAVTOxp zUy0h!usiFJ`;Tp#`LVIgiZzR?9zr|49;36`Sm&s7x;9N<`J$8hna7&@3%v`jr5GukG0ymk>CDy|7Qp=U_ z{CrC(M-InF)k*^3P&(Ga;*z4pC6-bu6iVM#VlkO-Q;USc!55WS1*MBitt+@T!{~@brDf%X&_%u&2DcV2HQChKgu(NR3W2={4P(9v zZpwppz6Cz0h>-eNONo-kAOsF+gBc<4GHZba{WeUW<@M|8og3;?Cs(DZJ#IoQ1AtYz zDmPGAUcbJwwx-I6uh&5XVQpo7RjtDXH2xGiDGLYzIEJ~)QCYRgXs>m;9ds3gKV?p1 zU1j|yqqD(Lk3n5u@34Ddt|k~4IbCb;*J5E5cmbocwkjmw9Vq`->!HyvsByb%>et}U z%{E}bR=U=B>m2o-8O)@`P(QbEgUbn&z+js}MZYD#-dndC780`B9ksPs02G?atV?OE zFEbTu>=^pyvZ9h(Xk1%t02WkwTs0ewcF0b0X}UDpD(&ln<^#ffD;~<1qB!dI|12NS zV^s~w2TpEMoy+0zy6U+=S_N;Up=q-gT5dFMaJtsHjn4YoO-6281M(Z~Yb#wwG$&bG z*xrpWM62<~Q`fm`Hah}x<~zM;5c+$*ylVKHzMK^_?5f-ZhD)uMWrQ1BUU*9(86g@B zb0^cTl|ODreU-7u?WHBE!ZmRJgk%HZq+y3wrmWJ^AJzE&_Fy@wPM-kU;t z#srO!7L?c5VnU@7b&idEBAH<GDuzmRSqQBxTGFv`xOP zsMKPzQJ3LQS$;8%Rfs;ArUDi%$-pfvZ7#}3={!^ZEv3AGHhx3o3e<%$&PyfBzz5St znWa!mTeWfRMtfu8r-g@_Kh0>;1~3iPX(S`+uyDo?gsQ{Pc@@%NRU8xRCCpISi%PWuYQD`mV$TdKplw38MrGcvg*}89_?y|Z7fZ%QY8N&|yY5gag#GPl74#4J#%T4rl343%wVo%m@XCDd8M+Gi z-w){0>esD>J)!l*CbvOkjQ=g}l)8GVUBhz5Mj#BpQqt4ey?{M32;0d24tFc`Kcj|B zdkT&&(0&*%sf3fBZm&iMmXU@#ht0?@fvY~>L^%E7uoVOw2!mNU9n>Sajrg8Y}-CA8-9(#(_ z#Odt~gRS87T0&uEDqd?COvUR0Y-c3+Y$V;mhIz5Mr@A@RH2ppH_bILFmX`4Bx%K!v z=|NZq!CCzZW7-iG`WKtDVU#4B)g3!~XW&k#1NDw;*lj!4%f#jvERp)9EkVdfB)G&`|D z7o}rSd2o|X(X%N~YTU*s7WE9$aMePVOJolXPN4E95dnGQ-*k7PT7JwWm;iD!V~9?pt--L-p~- zFfaHCRWYa&>P2;$F^tVv8_C9b1U9Z}7#mlXz{cUm{5aQ`{^Xufts(8WN;f8!jmeB* zBQe#CEQ9Q`h5m$|xQ5Zw;@Q}>dX`)@k|mdoV9A-oS@ORp^^fRDY@qgq>0oNRpiRoq zCeR19%jj`bmtm+&0uvsI3*tuL-zZ2&Au5M=xFLoaJVTiQ`ZA!bVfOHzQLr^=A@=?) zjNO7&3)voeUO=3Fpc+VPZCpH@_ebcyB)WmhqWiNifH$H5_u{p(GSc*O+JD#58Hg_k z$*1(fko=)zqM;9gjd7tx8b+=nx>R2;aPGi@rUPjTc^yh3igiPEY$)1F7Zb%|Tu}{? ztI%H)qF6%aP?j(|x_Bt{(}|1)=zOn~vFpni`x%c?V88fGf2OHw+kdEuEZP@0&@Yj7O=z+ z*du@y19l<=_99@3;F}u)dk3&a;1!3!E&#R*uy1?*>A&V$X^c>n^H2Y^=CA($#eco5 zban-Hg;lk+@FhmqZCvc|`MhRz-9|3b6J)Wl6)teEDck75Q9q@ZRl4dmz)O@a zR(FWID4q}JaDl1JX3ARz_ixeayWk#Te#$Xt zi}Qh9SLa;sz&f|0BEQ1j;IP+J*Vrqxy*Xo(0e5?4V<3=qP z5Cyjbv8DMX<%P5doRyibwvmTbb2kC*6timD88aV)gSxVc-OsAs4#zsy%&KwBUCSO| z)f-$j9<)|6VIUmCfC%TeofWZ4kFy$9j=~zo9%kTQZ*SPd*0LIRRm~bm`Z)7A;TU$f z*a22u>vX!etu6DMr1BvCJ?GXT1Z8ukcjzo;Q(II5s-$UXP<9EMpY- z5gzU0Yo^z^r*EjKpKf<~rbE#+&gr$Yrq7zLs_=^ZwT{Y$(CjPALki4so=}u4C_r^^ zv4kRANu#dPv-WT0gM+@>W!dr#8Q`0sb^cz7vN4=)S)rn9b>2=WPhg$d-DK z3!~{n%2`_D@^~w2%j+R}6=T2Em)EOZuFA5}?r0z<-6GyV_?4i()ZzK7*<&Nf3V2;E zv_`SZX?I{t@Pxh$&0bTF0UH3Z=18ksOE_JNFqTo*VwVH{H4iI}y4CA&Z7O!S;L?G| z)eb2jC3@4itEpS7*u)TM*;?w*0J469mTq!;9Cc+-kjV`J928>{b>DolY*Uf4pt>~s|2P?HPc;gP^sp_{CC2)h& z`#5fS;L)KHw5FJ8)M_)Jh6MlT^FK%fiSPpAEyEgveuw&~7T=BVf#FzpyYV92JA$z% z5vQ;MdzY1nhx!W0hwzROek1r1csPl%c+ea`D9^yZQHOXx!Y5~{`+d59^>jLXD1h%q zc;{^F1&AiX>oRbe4DissKlurMgx3Q&h0o*Ni8zJ(@ji)oE5Zet*hirbp?iGV>u1bC zJ%B^udc4eyeFnk@<}#Lr_%4Ko9Nd3F+=%c3-j%>-^B8*wZ#v?%SNjNOH$=Z5;bVFD zcj$n>8zKE&_-@4e5tc0mf8eh|Xvb#!9N^^7OTm7xf$$N&ikEcWitu{usiQD+rX#!+ zZzAGl2>h({kw#}!b^I45uuE?7I6yq6=B~_ zWf4v2kviLeuA+Tm>kZk1=u|7VH|aA3OXa=M+>p6R%@F}KoPH)H**iF7VpQ;mhVc7tX9#91@a zCoV|9m5+HI7mnSmSgHS=)H2j^DCx#p6|3+~oDLn{%p>OsxHzh??^uuJ%o>M#Ff%mU z!k4*NwAmc%9k|Rw-}w_O-8eCGu5-918of0pJFU&;Ppq!2bvq_5m^X8fc6i}I`XLxs zai2FctgiEB4hoIp^JWJ0xuDooj0+vOZnAv27WuEF$;Xp|wrzc;>zNbJbU)McjPZrk b7g}C8@j~|t8}~Hs*|`Uq|9t+(YT*9@pLPB{ literal 0 HcmV?d00001 diff --git a/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/whatsnew.txt b/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/whatsnew.txt new file mode 100644 index 0000000000..b0c8c59bb2 --- /dev/null +++ b/libraries/SITL/examples/JSON/MATLAB/tcp_udp_ip_2.0.6/whatsnew.txt @@ -0,0 +1,90 @@ +History of tcp/udp/ip toolbox for MATLAB +======================================== + +Version 2.0.6 2008-03-06 + + -Including precompiled pnet.mexw32 for support to in matlab R2007 (R2008?) + No need to compile pnet.c to run at R2007.... + (Included a real application demo that uses UDP and simulates a UDP based DAQ system.) + +Version 2.0.5 2003-09-16 + -Fixing all GNU License notes more proper and clear and writing an + exception that make it "100%" legal and proper to use this as a plug-in + as the basic intention of cause is. The note also makes it clear that + you can link and distribute this toolbox as non-free stand alone as long as + this part (the tcp_udp_ip toolbox) is distributed with it and fullfills + the licence agreement for it. See license.txt + + - The windows dll is compiled with matlab 5.3 to make it possible to + run in matlab 5.x + +Version 2.0.4 2003-07-22 + -Major bug fix: 'readtofile' and 'writefromfile' now opens the files in + binary mode also for the Windows platform which makes the toolbox work properly + for many cases where it erlier failed. This probably solvs many bugs + that could not be solved. erlier! + -changed call frequency of 'drawnow' from 1 per sec to 10 per seconds. + -'pnet_remote' now supports an array of conection handles for calls that + do not return any thing. + - new author adress information + +Version 2.0.3 2002-04-23 + -Added support for the "single" (float 32-bit) datatype. + +Version 2.0.2 2002-03-12 + Windows buggfixes (also bugs for unix): + -Breaking blocking operations with ctrl-c now works (better..) + Fixed with a call to drawnow evry second. + -UDP receive of packets now works stable after initialzing fromlen + in revfrom() call. + +Version 2.0.1 2002-02-25 + -Long delays in windows is fixed by changing Sleep(...) in pnet.c + to correspond to sleep(...) in unix by div. by 1000. + -Added drawnow into SERVER loop in pnet_remote. + +Version 2.0 (Beta) 2002-02-14 + Complete rewrite of the API with new calls. + All tcpip_* function is replaced with new mex function named pnet(....). + NEW mutch faster support for datatypes and byte swapping!! + Datatype support: double,char,uint8,unint16,uint32,int8,nint16,int32. + Byte swapping support: native,swap,intel,network byte orders. + tcpip_feval family function replaced by the pnet_remote function. + This version in not backwards compatible wit version 1.x but + are similar -> easy to port (easy to write wrapper functions?) + +Version 1.3 2001-01-13 + Added support to UDP/IP-packet transmission by Mike Medeiros + This version is never published...... + +Verion 1.2.1 2001-01-04 + + Bugfix of variable and file tranfer functions + Prelimnaray remote execution interface! + +Version 1.2 2000-12-14 + + tcpip_servopen() replace by tcpip_servsocket() and + tcpip_listen() Now its a non blocking multi connection + server!! + A simple webserver_demo is now also included. + +Version 1.2 BETA 2000-11-20 + + Bug fixed. multi connections work proper! + + +Version 1.1 1999-10-28 + + Now also support for Windows 95/98(?)/NT4 By Mario Bergeron + All data types is now supported to be sent/rec. in network byte + order. Solaris and Linux also seams to work well without + "broke pipe handling" bug! + A demo that reads mail from a pop mail server is also included. + + +Version 1.0 Beta 1 1999-04-06 + + Open connections as client or server and send/receive + text strings. Works under Linux and Solaris. + Under soloris some trouble with "broken pipe handling"