source: ResearchApps/PHY/WARPLAB/WARPLab7/M_Code_Reference/classes/wl_transport_eth_udp_mex.m

Last change on this file was 4818, checked in by welsh, 5 years ago

Added version checking for MEX transport; Added error checking to help with version errors.

File size: 30.3 KB
Line 
1%-------------------------------------------------------------------------
2% WARPLab Framework
3%
4% Copyright 2013, Mango Communications. All rights reserved.
5%           Distributed under the WARP license  (http://warpproject.org/license)
6%
7% Chris Hunter (chunter [at] mangocomm.com)
8% Patrick Murphy (murphpo [at] mangocomm.com)
9% Erik Welsh (welsh [at] mangocomm.com)
10%-------------------------------------------------------------------------
11
12classdef wl_transport_eth_udp_mex < wl_transport & handle_light
13% Mex physical layer Ethernet UDP Transport for unicast traffic
14% User code should not use this object directly-- the parent wl_node will
15% instantiate the appropriate transport object for the hardware in use
16
17%******************************** Properties **********************************
18
19    properties (SetAccess = public)
20        timeout;             % Maximum time spent waiting before retransmission
21    end
22
23    properties (SetAccess = protected, Hidden = true)
24        sock;                % UDP socket
25        status;              % Status of UDP socket
26        maxSamples;          % Maximum number of samples able to be transmitted (based on maxPayload)
27        maxPayload;          % Maximum payload size (e.g. MTU - ETH/IP/UDP headers)
28    end
29
30    properties (SetAccess = protected)
31        address;             % IP address of destination
32        port;                % Port of destination
33    end
34   
35    properties (SetAccess = public)
36        hdr;                 % Transport header object
37        rxBufferSize;        % OS's receive buffer size in bytes
38    end
39
40    properties(Hidden = true, Constant = true)
41        % These constants define specific command IDs used by this object.
42        % Their C counterparts are found in wl_transport.h
43        GRP                            = 'transport';
44        CMD_PING                       = 1;                % 0x000001
45        CMD_PAYLOADSIZETEST            = 2;                % 0x000002
46       
47        CMD_NODEGRPID_ADD              = 16;               % 0x000010
48        CMD_NODEGRPID_CLEAR            = 17;               % 0x000011
49       
50        TRANSPORT_NOT_READY_MAX_RETRY  = 50;
51        TRANSPORT_NOT_READY_WAIT_TIME  = 0.1;
52       
53        REQUIRED_MEX_VERSION           = '1.0.4a';         % Must match version in MEX transport
54    end
55
56
57%********************************* Methods ************************************
58
59    methods
60
61        function obj = wl_transport_eth_udp_mex()
62            obj.hdr         = wl_transport_header;
63            obj.hdr.pktType = obj.hdr.PKTTYPE_HTON_MSG;
64            obj.status      = 0;
65            obj.timeout     = 1;
66            obj.maxPayload  = 1000;    % Sane default. This gets overwritten by CMD_PAYLOADSIZETEST command.
67            obj.port        = 0;
68            obj.address     = '10.0.0.0';
69           
70            obj.checkSetup();
71        end
72       
73        function checkSetup(obj)
74            % Check to make sure wl_mex_udp_transport exists and is is configured
75            %
76            temp = which('wl_mex_udp_transport');
77           
78            if(isempty(temp))
79                error('wl_transport_eth_udp_mex:constructor', 'WARPLab Mex UDP transport not found in Matlab''s path');
80            elseif(strcmp(temp((end-length(mexext)+1):end ), mexext) == 0)
81                error('wl_transport_eth_udp_mex:constructor', 'WARPLab Mex UDP transport found, but it is not a compiled mex file');
82            end
83           
84            version     = wl_mex_udp_transport('version');
85            version     = sscanf(version, '%d.%d.%d%c');
86            version_req = sscanf(obj.REQUIRED_MEX_VERSION, '%d.%d.%d%c');
87
88            % Version must match required version   
89            if(~(version(1) == version_req(1) && version(2) == version_req(2) && version(3) == version_req(3) && version(4) >= version_req(4)))
90                version     = wl_mex_udp_transport('version');
91                version_req = obj.REQUIRED_MEX_VERSION;
92               
93                error('wl_transport_eth_udp_mex:constructor', 'MEX transport version mismatch.\nRequires version %s, found version %s', version_req, version);
94            end
95        end
96       
97        function setMaxPayload(obj, value)
98       
99            if (isempty(value))
100               error('wl_transport_eth_udp_mex:setMaxPayload', 'setMaxPayload requires a non-empty argument.');
101            else
102                obj.maxPayload = value;
103           
104                % Compute the maximum number of samples in each Ethernet packet
105                %   - Start with maxPayload is the max number of bytes per packet (nominally the Ethernet MTU)
106                %   - Subtract sizes of the transport header, command header and samples header
107                %   - Due to DMA alignment issues in the node, the max samples must be 4 sample aligned.
108                obj.maxSamples = double(bitand(((floor(double(obj.maxPayload)/4) - sizeof(obj.hdr)/4 - sizeof(wl_cmd)/4) - (sizeof(wl_samples)/4)), 4294967292));
109               
110                % fprintf('Max samples: %d\n', obj.maxSamples);
111            end
112        end
113       
114        function out = getMaxPayload(obj)
115            out = double(obj.maxPayload);
116        end
117
118        function setAddress(obj, value)
119            if(ischar(value))
120                obj.address = value;
121            else
122                obj.address = obj.int2IP(value);
123            end
124        end
125       
126        function out = getAddress(obj)
127            out = obj.address;
128        end
129       
130        function setPort(obj, value)
131            obj.port = value;
132        end
133       
134        function out = getPort(obj)
135            out = obj.port;
136        end
137
138        function open(obj,varargin)
139            % varargin{1}: (optional) IP address
140            % varargin{2}: (optional) port
141            %
142            if(nargin==3)
143               obj.setAddress(varargin{1});
144               obj.port = varargin{2};
145            end
146
147            REQUESTED_BUF_SIZE = 2^22;
148             
149            % Call to 'init_sockets' will internally call setReuseAddress and setBroadcast
150            obj.sock = wl_mex_udp_transport('init_socket');
151            wl_mex_udp_transport('set_so_timeout', obj.sock, 1);
152            wl_mex_udp_transport('set_send_buf_size', obj.sock, REQUESTED_BUF_SIZE);
153            wl_mex_udp_transport('set_rcvd_buf_size', obj.sock, REQUESTED_BUF_SIZE);
154
155            x = wl_mex_udp_transport('get_rcvd_buf_size', obj.sock);           
156            obj.rxBufferSize = x;
157
158            if(x < REQUESTED_BUF_SIZE)
159                fprintf('OS reduced recv buffer size to %d\n', x);
160            end
161           
162            obj.status = 1;
163        end
164       
165        function out = procCmd(obj,nodeInd,node,cmdStr,varargin)
166            % wl_node procCmd(obj, nodeInd, node, varargin)
167            %     obj:       Node object (when called using dot notation)
168            %     nodeInd:   Index of the current node, when wl_node is iterating over nodes
169            %     node:      Current node object
170            %     cmdStr:    Command string of the interface command
171            %     varargin:
172            %         [1:N}  Command arguments
173            %
174            out    = [];
175           
176            cmdStr = lower(cmdStr);
177            switch(cmdStr)
178           
179                %---------------------------------------------------------
180                case 'ping'
181                    % Test to make sure node can be accessed via this
182                    % transport
183                    %
184                    % Arguments: none
185                    % Returns: true if board responds; raises error otherwise
186                    %
187                    myCmd = wl_cmd(node.calcCmd(obj.GRP,obj.CMD_PING));
188                    node.sendCmd(myCmd);
189                    out = true;                            % sendCmd will timeout and raise error if board doesn't respond
190                   
191                %---------------------------------------------------------
192                case 'payload_size_test'
193                    % Determine objects maxPayload parameter
194                    %
195                    % Arguments: none
196                    % Returns: none
197                    %
198                    configFile = which('wl_config.ini');
199                   
200                    if(isempty(configFile))
201                       error('cannot find wl_config.ini. please run wl_setup.m'); 
202                    end
203                   
204                    readKeys = {'network', '', 'max_transport_payload_size', ''};
205                    max_transport_payload_size = inifile(configFile, 'read', readKeys);
206                    max_transport_payload_size = str2num(max_transport_payload_size{1});
207                   
208                    % Determine the payloads to test
209                    payloadTestSizes = [];
210
211                    for i = [1000 1470 5000 8966]
212                        if (i < max_transport_payload_size) 
213                            payloadTestSizes = [payloadTestSizes, i];
214                        end
215                    end
216                   
217                    payloadTestSizes = [payloadTestSizes, max_transport_payload_size];
218                                       
219                    % WARPLab Header is (see http://warpproject.org/trac/wiki/WARPLab/Reference/Architecture/WireFormat ):
220                    %   - 2 byte pad
221                    %   - Transport header
222                    %   - Command header
223                    payloadTestSizes = floor((payloadTestSizes - (sizeof(node.transport.hdr) + sizeof(wl_cmd) + 2)) / 4);
224                   
225                    for index = 1:length(payloadTestSizes)
226                        myCmd = wl_cmd(node.calcCmd(obj.GRP,obj.CMD_PAYLOADSIZETEST));
227                        myCmd.addArgs(1:payloadTestSizes(index));
228                        try                       
229                            resp = node.sendCmd(myCmd);
230                            obj.setMaxPayload(resp.getArgs);
231                            if(obj.getMaxPayload() < (payloadTestSizes(index) * 4))
232                               break; 
233                            end
234                        catch ME
235                            break 
236                        end
237                    end
238                   
239                %---------------------------------------------------------
240                case 'add_node_group_id'
241                    % Adds a Node Group ID to the node so that it can
242                    % process broadcast commands that are received from
243                    % that node group.
244                    %
245                    % Arguments: (uint32 NODE_GRP_ID)
246                    % Returns: none
247                    %
248                    % NODE_GRP_ID: ID provided by wl_node_grp
249                    %
250                    myCmd = wl_cmd(node.calcCmd(obj.GRP, obj.CMD_NODEGRPID_ADD));
251                    myCmd.addArgs(varargin{1});
252                    node.sendCmd(myCmd);
253                   
254                %---------------------------------------------------------
255                case 'clear_node_group_id'
256                    % Clears a Node Group ID from the node so it can ignore
257                    % broadcast commands that are received from that node
258                    % group.
259                    %
260                    % Arguments: (uint32 NODE_GRP_ID)
261                    % Returns: none
262                    %
263                    % NODE_GRP_ID: ID provided by wl_node_grp
264                    %
265                    myCmd = wl_cmd(node.calcCmd(obj.GRP, obj.CMD_NODEGRPID_CLEAR));
266                    myCmd.addArgs(varargin{1});
267                    node.sendCmd(myCmd);
268                   
269                %---------------------------------------------------------
270                otherwise
271                    error('unknown command ''%s''',cmdStr);
272            end
273           
274            if((iscell(out) == 0) && (numel(out) ~= 1))
275                out = {out}; 
276            end     
277        end
278       
279        function close(obj)           
280            if(~isempty(obj.sock))
281                try
282                    wl_mex_udp_transport('close', obj.sock);
283                catch closeError
284                    warning( 'Error closing socket; mex error was %s', closeError.message)
285                end
286            end
287            obj.status=0;
288        end
289       
290        function delete(obj)
291            obj.close();
292        end
293       
294        function flush(obj)
295            % Currently not implemented
296        end
297    end % methods
298
299   
300    methods (Hidden = true)
301
302        function reply = send(obj, send_data, response, varargin)
303            % send_data  : Data to be sent to the node
304            % response   : Does the transmission require a response from the node
305            % varargin{1}: (optional)
306            %     - increment the transport header; defaults to true if not specified
307            %
308
309            % Initialize variables
310            maxAttempts       = 2;                                   % Maximum times the transport will re-try a packet
311            payload           = uint32(send_data);                   % Change data to 32 bit unsigned integers for transmit
312            obj.hdr.msgLength = ((length(payload)) * 4);             % Length in bytes (4 bytes / sample)
313            reply             = [];                                  % Initialize array for response from the node
314            robust            = response;
315
316            % Process command line arguments
317            increment_hdr     = true;
318
319            if (nargin == 4)
320               increment_hdr  = varargin{1};
321            end
322           
323            % Set the appropriate flags in the header           
324            if(robust)
325               obj.hdr.flags = bitset(obj.hdr.flags, 1, 1);
326            else
327               obj.hdr.flags = bitset(obj.hdr.flags, 1, 0);
328            end
329
330            % Increment the header and serialize all the data into a uint32 array
331            if (increment_hdr)
332                obj.hdr.increment;
333            end
334                       
335            % Format the data / address arguments for transmission
336            data     = [obj.hdr.serialize, payload];                                      % Get a unified array with the header and data
337            data8    = [zeros(1,2,'uint8') typecast(swapbytes(uint32(data)), 'uint8')];   % Change to uint8 and pad by 2 bytes so payload is 32 bit aligned w/ Eth header
338
339            % Send the packet
340            size = wl_mex_udp_transport('send', obj.sock, data8, length(data8), obj.address, obj.port);
341
342            % Wait to receive reply from the board               
343            if(robust == 1)
344                MAX_PKT_LEN      = obj.getMaxPayload() + 100;
345                hdr_length       = obj.hdr.length;
346                currTx           = 1;
347                numWaitRetries   = 0;
348                receivedResponse = 0;
349                currTime         = tic;
350
351                while (receivedResponse == 0)
352                    try
353                        [recv_len, recv_data8] = wl_mex_udp_transport('receive', obj.sock, MAX_PKT_LEN);
354
355                    catch receiveError
356                        error('%s.m -- Failed to receive UDP packet.\nMEX transport error message follows:\n    %s\n', mfilename, receiveError.message);
357                    end
358                   
359                    % If we have a packet, then process the contents
360                    if(recv_len > 0)
361                        reply8     = [recv_data8(3:recv_len) zeros(mod(-(recv_len - 2), 4), 1, 'uint8')];
362                        reply      = swapbytes(typecast(reply8, 'uint32'));
363
364                        % Check the header to see if this was a valid reply                       
365                        if(obj.hdr.isReply(reply(1:hdr_length)))
366                       
367                            % Check the header to see if we need to wait for the node to be ready
368                            if (obj.hdr.isNodeReady(reply(1:hdr_length)))
369                           
370                                % Strip off transport header to give response to caller
371                                reply  = reply((hdr_length + 1):end);
372                               
373                                if(isempty(reply))
374                                    reply = []; 
375                                end
376                               
377                                receivedResponse = 1;
378                               
379                            else
380                                % Node is not ready; Wait and try again
381                                pause(obj.TRANSPORT_NOT_READY_WAIT_TIME);
382                                numWaitRetries = numWaitRetries + 1;
383
384                                % Send packet packet again
385                                obj.sock.send(pkt_send);
386
387                                % Check that we have not spent a "long time" waiting for samples to be ready               
388                                if (numWaitRetries > obj.TRANSPORT_NOT_READY_MAX_RETRY)
389                                    error('wl_transport_eth_mex:send:isReady', 'Error:  Timeout waiting for node to be ready.  Please check the node operation.');
390                                end
391                               
392                                reply = [];
393                            end
394                        end
395                    end
396                   
397                    % Look for timeout
398                    if ((toc(currTime) > obj.timeout) && (receivedResponse == 0))
399                        if(currTx == maxAttempts)
400                            error('wl_transport_eth_mex:send:noReply', 'maximum number of retransmissions met without reply from node'); 
401                        end
402                       
403                        % Retry the packet
404                        size = wl_mex_udp_transport('send', obj.sock, data8, length(data8), obj.address, obj.port);
405                        currTx   = currTx + 1;
406                        currTime = tic;
407                    end
408                end
409            end
410        end
411       
412        function resp = receive(obj)
413            % Receive all packets from the Ethernet interface and pass array
414            %     of valid responses to the caller.
415            %
416            % NOTE:  This function will strip off the transport header from the responses
417            % NOTE:  This function is non-blocking and will return an empty response if
418            %            there are no packets available.
419            %
420
421            % Initialize variables
422            MAX_PKT_LEN = obj.getMaxPayload() + 100;           
423            hdr_length  = obj.hdr.length;
424            done        = false;
425            resp        = [];
426           
427            while ~done
428                try
429                    [recv_len, recv_data8] = wl_mex_udp_transport('receive', obj.sock, MAX_PKT_LEN);
430
431                catch receiveError
432                    error('%s.m -- Failed to receive UDP packet.\nMEX transport error message follows:\n    %s\n', mfilename, receiveError.message);
433                end
434               
435                if(recv_len > 0)
436                    reply8 = [recv_data8(3:recv_len) zeros(mod(-(recv_len - 2), 4), 1, 'uint8')].';
437                    reply  = swapbytes(typecast(reply8, 'uint32'));
438
439                    if(obj.hdr.isReply(reply(1:hdr_length)))
440                        % Strip off transport header to give response to caller
441                        reply  = reply((hdr_length + 1):end);
442                       
443                        if(isempty(reply))
444                            reply = [];
445                        end
446                       
447                        resp = [resp, reply];                       
448
449                        done = true;
450                    end
451                else
452                    done = true;
453                end
454            end
455        end
456       
457        function dottedIPout = int2IP(obj,intIn)
458            addrChars(4) = mod(intIn, 2^8);
459            addrChars(3) = mod(bitshift(intIn, -8), 2^8);
460            addrChars(2) = mod(bitshift(intIn, -16), 2^8);
461            addrChars(1) = mod(bitshift(intIn, -24), 2^8);
462            dottedIPout = sprintf('%d.%d.%d.%d', addrChars);
463        end
464       
465        function intOut = IP2int(obj,dottedIP)
466            addrChars = sscanf(dottedIP, '%d.%d.%d.%d')';
467            intOut = 2^0 * addrChars(4) + 2^8 * addrChars(3) + 2^16 * addrChars(2) + 2^24 * addrChars(1);
468        end
469       
470        function reply = print_cmd(obj, type, num_samples, start_sample, buffer_ids, command)
471            fprintf('Command:  %s \n', type);
472            fprintf('    # samples  = %d    start sample = %d \n', num_samples, start_sample);
473            fprintf('    buffer IDs = ');
474            for index = 1:length(buffer_ids)
475                fprintf('%d    ', buffer_ids(index));
476            end
477            fprintf('\n    Command (%d bytes): ', length(command) );
478            for index = 1:length(command)
479                switch(index)
480                    case 1
481                        fprintf('\n        Padding  : ');
482                    case 3
483                        fprintf('\n        Dest ID  : ');
484                    case 5
485                        fprintf('\n        Src ID   : ');
486                    case 7
487                        fprintf('\n        Rsvd     : ');
488                    case 8
489                        fprintf('\n        Pkt Type : ');
490                    case 9
491                        fprintf('\n        Length   : ');
492                    case 11
493                        fprintf('\n        Seq Num  : ');
494                    case 13
495                        fprintf('\n        Flags    : ');
496                    case 15
497                        fprintf('\n        Command  : ');
498                    case 19
499                        fprintf('\n        Length   : ');
500                    case 21
501                        fprintf('\n        # Args   : ');
502                    case 23
503                        fprintf('\n        Args     : ');
504                    otherwise
505                        if ( index > 23 ) 
506                            if ( ( mod( index + 1, 4 ) == 0 ) && not( index == length(command) ) )
507                                fprintf('\n                   ');
508                            end
509                        end
510                end
511               fprintf('%2x ', command(index) );
512            end
513            fprintf('\n\n');
514           
515            reply = 0;
516        end
517
518        %-----------------------------------------------------------------
519        % read_buffers
520        %     Command to utilize additional functionality in the wl_mex_udp_transport C code in order to
521        %     speed up processing of 'readIQ' and 'readRSSI' commands
522        %
523        % Supports the following calling conventions:
524        %    - start_sample -> must be a single value
525        %    - num_samples  -> must be a single value
526        %    - buffer_ids   -> Can be a vector of single RF interfaces
527        %
528        function reply = read_buffers(obj, func, num_samples, buffer_ids, start_sample, seq_num_tracker, seq_num_match_severity, node_id_str, wl_command, input_type)
529            % func                     : Function within read_buffers to call
530            % number_samples           : Number of samples requested
531            % buffer_ids               : Array of Buffer IDs
532            % start_sample             : Start sample
533            % seq_num_tracker          : Sequence number tracker
534            % seq_num_match_severity   : Severity of message when sequence numbers match on reads
535            % node_id_str              : String representation of Node ID
536            % wl_command               : Ethernet WARPLab command
537            % input_type               : Type of sample array:
538            %                                0 ==> 'double'
539            %                                1 ==> 'single'
540            %                                2 ==> 'int16'
541            %                                3 ==> 'raw'
542
543            % Get the lowercase version of the function           
544            func = lower(func);
545
546            % Calculate how many transport packets are required
547            numPktsRequired = ceil(double(num_samples)/double(obj.maxSamples));
548
549            % Arguments for the command will be set in the MEX function since it is faster
550            %     wl_command.setArgs(buffer_id, start_sample, num_samples, obj.maxSamples * 4, numPktsRequired);
551           
552            % Construct the minimal WARPLab command that will be used used to get the samples
553            %   NOTE:  Since we did not add the arguments of the command thru setArgs, we need to pad the structure so that
554            %          the proper amount of memory is allocated to be available to the MEX
555            payload           = uint32( wl_command.serialize() );        % Convert command to uint32
556            cmd_args_pad      = uint32( zeros(1, 5) );                   % Padding for command args
557            obj.hdr.flags     = bitset(obj.hdr.flags,1,0);               % We do not need a response for the sent command
558            obj.hdr.msgLength = ( ( length( payload ) ) + 5) * 4;        % Length in bytes
559
560            data  = [obj.hdr.serialize, payload, cmd_args_pad];
561            data8 = [zeros(1,2,'uint8') typecast(swapbytes(uint32(data)), 'uint8')];
562
563            % Pass all of the command arguments down to MEX
564            switch(func)
565                case 'iq'
566                    % Calls the MEX read_iq command
567                    %
568                    % obj.print_cmd('READ_IQ', num_samples, start_sample, buffer_ids, data8);
569                   
570                    [num_rcvd_samples, cmds_used, rx_samples]  = wl_mex_udp_transport('read_iq', obj.sock, data8, length(data8), obj.address, obj.port, num_samples, buffer_ids, start_sample, obj.maxSamples * 4, numPktsRequired, input_type, seq_num_tracker, seq_num_match_severity, node_id_str);
571                   
572                    % Code to test higher level matlab code without invoking the MEX transport
573                    %
574                    % rx_samples = zeros( num_samples, 1 );
575                    % cmds_used  = 0;
576
577                case 'rssi'
578                    % Calls the MEX read_rssi command
579                    %                       
580                    % obj.print_cmd('READ_RSSI', num_samples, start_sample, buffer_ids, data8);
581
582                    [num_rcvd_samples, cmds_used, rx_samples]  = wl_mex_udp_transport('read_rssi', obj.sock, data8, length(data8), obj.address, obj.port, num_samples, buffer_ids, start_sample, obj.maxSamples * 4, numPktsRequired, input_type, seq_num_tracker, seq_num_match_severity, node_id_str);
583
584                    % Code to test higher level matlab code without invoking the MEX transport
585                    %
586                    % rx_samples = zeros( num_samples * 2, 1 );
587                    % cmds_used  = 0;
588
589                otherwise
590                    error('unknown command ''%s''', cmdStr);
591            end
592           
593            obj.hdr.increment(cmds_used);
594           
595            reply = rx_samples;
596        end
597 
598 
599        %-----------------------------------------------------------------
600        % write_buffers
601        %     Command to utilize additional functionality in the wl_mex_udp_transport C code in order to
602        %     speed up processing of 'writeIQ' commands
603        %
604        function reply = write_buffers(obj, func, num_samples, samples, buffer_ids, start_sample, hw_ver, wl_command, check_chksum, input_type)
605            % func           : Function within read_buffers to call
606            % number_samples : Number of samples requested
607            % samples        : Array of IQ samples
608            % buffer_ids     : Array of Buffer IDs
609            % start_sample   : Start sample
610            % hw_ver         : Hardware version of the Node
611            % wl_command     : Ethernet WARPLab command
612            % check_chksum   : Perform the WriteIQ checksum check inside the function
613            % input_type     : Type of sample array:
614            %                      0 ==> 'double'
615            %                      1 ==> 'single'
616            %                      2 ==> 'int16'
617            %                      3 ==> 'raw'
618           
619            % Calculate how many transport packets are required
620            num_pkts_required = ceil(double(num_samples)/double(obj.maxSamples));
621
622            % Construct the WARPLab command that will be used used to write the samples
623            payload           = uint32( wl_command.serialize() );        % Convert command to uint32
624            obj.hdr.flags     = bitset(obj.hdr.flags,1,0);               % We do not need a response for the sent command
625            obj.hdr.msgLength = ( length( payload ) ) * 4;               % Length in bytes
626           
627            data              = [obj.hdr.serialize, payload];
628            data8             = [zeros(1,2,'uint8') typecast(swapbytes(uint32(data)), 'uint8')];
629           
630            socket            = obj.sock;
631            address           = obj.address;
632            port              = obj.port;
633            max_payload       = obj.getMaxPayload();
634            max_samples       = obj.maxSamples;
635           
636
637            func = lower(func);
638            switch(func)
639                case 'iq'
640                    % Calls the MEX read_iq command
641                    %
642                    [cmds_used, checksum] = wl_mex_udp_transport('write_iq', socket, data8, max_payload, address, port, num_samples, samples, buffer_ids, start_sample, num_pkts_required, max_samples, hw_ver, check_chksum, input_type);
643                   
644                    % Increment the transport header by cmds_used (ie number of commands used
645                    obj.hdr.increment(cmds_used);
646                   
647                    % Record the checksum for that Write IQ
648                    reply = checksum;
649                   
650                otherwise
651                    error('unknown command ''%s''',cmdStr);
652            end
653           
654            reply = checksum;
655        end
656    end
657end % classdef
658
659
660
661
Note: See TracBrowser for help on using the repository browser.