Audio/Variodyn/PaProtocol

From eqqon

Jump to: navigation, search

Contents

The PA Protocol

The Variodyn D1 system can be controlled via commands transmitted via ethernet. the protocol used was designed around 1993 to handle new communication requirements. as initially designed for serial communication the protocol has a robust resynchronisation ability, and a weak checksum algorithm which can be implemented easily on small microcontrollers. Nowadays, the protocol is used inside a TCP channel to communicate with a controlling computer via ethernet. The TCP channel provides a session layer and also error correction and retransmission, so the weak checksum algorithm of the protocol itself is no longer a drawback.


Version 7 (german only)

This is the latest version used by Variodyn 3000 and early versions of the Variodyn D1 Software. Documentation and usage is not public available.


Version 8 (german only)

Several extensions used by the Variodyn D1 System since Version 1.8 are added. Documentation available after registration, usage is limited to AV Digital devices.

supported by DOM V1.8, V1.9, V2.0, V2.1

Version 9 (english only)

There exists a nearly free documentation of the PA Protocol. Nearly free means, the document can be copied and distributed with only one requirement: you have to register.

The PA Protocol can be implemented and used free with also only one requirement: one endpoint of commnucation has to be a AV Digital device.

The PA Protocol is not available for download.


PRECONDITIONS: the following FAQ and comments to the PA protocol requires knowlege of the PA protocol. This document cannot be published without registration due to AV Digital's license. You have to request the document at AV Digital.

Frequently asked questions

It's not clear when transmitted characters has to be expanded. When has a transmitted or received byte to be expanded?
The Data Extension has to be done if a transmitted byte has data meaning and the value of the byte is at the control symbol range 0xf9 ... 0xff. The data symbols table gives an overview.
Data symbols
value transmitted data over wire
message data 0FFh 0FFH 000H
message data 0FEh 0FFH 001H
message data 0FDh 0FFH 002H
message data 0FCh 0FFH 003H
message data 0FBh 0FFH 004H
message data 0FAh 0FFH 005H
message data 0F9h 0FFH 006H
message data 0F8h 0F8H
message data 0F7h 0F7H
message data 0F6h0F6H
.........
message data 001h 001H
message data 000h000H


How can i observe the complete message list from a DOM?
You can do this using the 'get news' command to observe a single news message with given index. To get the complete list, you have to read the all single messages by increasing the index until the DOM sends a return code not 0. See the following pseudocode:
message_index = 0
result = send_command_get_news(message_index)
while (result is 0)
begin
    wait until get_news_answer is there
    add ( read_get_news_answer() ) to news_list
    message_index = message_index + 1
    result = send_command_get_news(message_index)
end


I've seen more than one PA message inside a UDP packet. Is this allowed?
Yes. your implementation must handle more than one PA messages at one UDP packet.


Is it allowed to split a PA message over many UDP packets?
No. This is not allowed. If you do this the Receiver at the DOM will get confused. Also your implementation can ignore this. But the maximum size of a PA message is 10000 bytes. The typical ethernet MTU is ~1500 bytes using UDP. This oversized packets can be transmitted using IP fragmentation. which is supported by the DOM.

Implementation of the PA Protocol

First there are some helper macros to keep the protocol layer simple for programming. All messages are created on the heap, with maximal message size. The read and write functions automatically convert to/from network byte order.
/* helper macros to write pa protocol messages */
#define PAMSG_MAXSIZE 10000
typedef struct { unsigned char b[PAMSG_MAXSIZE], cs; int i; } pamsg_t;

#define pa_new_message(m, mid, d1,d2,d3,d4, s1,s2,s3,s4) \
  pamsg_t *(m) = (pamsg_t*)malloc(sizeof(pamsg_t));\
  (m)->i=0; (m)->cs=0;\
  (m)->b[(m)->i++]=0xfe;\
  pa_wr8(m,d1),pa_wr8(m,d2),pa_wr8(m,d3),pa_wr8(m,d4);\
  pa_wr8(m,s1),pa_wr8(m,s2),pa_wr8(m,s3),pa_wr8(m,s4);\
  pa_wr8(m,mid);\
  (m)->i=12;

#define pa_wr8(m,d) ((m)->b[(m)->i++]=(unsigned char)(d)>=0xf9?(m)->b[(m)->i++]=0xff,~(unsigned char)(d):(unsigned char)(d),(m)->cs+=(unsigned char)(d))
#define pa_wr16(m,d) (pa_wr8(m,(d)>>8),pa_wr8(m,(d)))
#define pa_wr32(m,d) (pa_wr8(m,(d)>>24),pa_wr8(m,(d)>>16),pa_wr8(m,(d)>>8),pa_wr8(m,(d)))

#define pa_finish_message(m) do{\
                        int j=(m)->i;\
                        if((j-12)%256>0xf9) memmove(&((m)->b[13]),&((m)->b[12]),j-12);\
                        (m)->i=10; pa_wr16(m,j-12);\
                        (m)->i=j;\
                        pa_wr8(m,0x100-(m)->cs);\
                        (m)->b[(m)->i++]=0xfd;\
                        }while(0)

#define pa_message_length(m) ((m)->i)

#define pa_delete_message(m) do { if(m) free(m); (m)=0; } while(0)
simple transmitter example - communication check
This example code creates a message from DOM 33 to DOM32 with message id 0x0b. There is one data byte (0x00) at the data body.
void main (void)
 {
 int i;
 pa_new_message(m, 0x0b, 0,33,1,0, 0,0x20,1,0);
 pa_wr8(m,0);
 pa_finish_message(m);
 
 /* send the message(m,pa_message_length(m)); */
 
 printf ("%10s [%d] bytes:","message",pa_message_length(m));
 for (i=0;i<pa_message_length(m);i++) printf (" %02x",m->b[i]); }
 printf("\n");
 pa_delete_message(m);
 }
simple receiver example -
/* suggest - untested code sample
#define pa_validate_message(m) do{\
                        int j=(m)->i=0;\
                        if((j-12)%256>0xf9) memmove(&((m)->b[13]),&((m)->b[12]),j-12);\
                        (m)->i=10; pa_wr16(m,j-12);\
                        (m)->i=j;\
                        pa_wr8(m,0x100-(m)->cs);\
                        (m)->b[(m)->i++]=0xfd;\
                        }while(0)
int pa_validate_message(pamsg_t *m) {
  int j;
  for (j=0,m->i=0; i<PAMSG_MAXSIZE && m->b[m->i]!=0xfd; ++m->i) {
    if (m->b[m->i] > 0xf9) { ++j; m->b[j]=~m->b[j]; }
    m->b[m->i] = m->b[j];
    }
  if((j-12)%256>0xf9) memmove(&((m)->b[13]),&((m)->b[12]),j-12);\
  (m)->i=10; pa_wr16(m,j-12);\
  (m)->i=j;\
  pa_wr8(m,0x100-(m)->cs);\
  (m)->b[(m)->i++]=0xfd;\
}
*/

PA Protocol examples

This section contains communication examples of representative scenarios of systems in use.

Example - activate and deactivate a audio route

A simple local audio route is activated, and deactivated again.

sequence diagram
DOM [loc. 99. sc. 0] PC [loc.103. ho. 0]


the DOM has no connections, and reports periodically an empty destination busy info.
Arrow lr.png RESPONSE destination busy info from [loc. 99. sc. 0] to [loc.255. ho. 0] mid[ 1] data: 87 00 00 00 00 63 01 00 01 00 04 87 00 00 00 0c


the PC activates a audio route from ai 0 to dd 4, priority 41, .
Arrow rl.png COMMAND activate route from [loc.103. sc. 0] to [loc. 99. sc. 0] mid[ 1] data: 00 94 2e 29 48 67 00 00 00 00 01 00 ff 00 00 00 00 01 63 10 00 01 08 00


the DOM executes the command, activates the audio route and sends a response back indicating the status.
Arrow lr.png RESPONSE activate route from [loc. 99. sc. 0] to [loc.103. sc. 0] mid[ 1] data: 80 00 94 2e 00 3d 00 00 00 00 09 80 00 94 2e 00 3d 00 00 00 ab
Arrow lr.png RESPONSE destination busy info from [loc. 99. sc. 0] to [loc.255. ho. 0] mid[ 1] data: 87 00 03 01 00 63 01 00 01 00 05 87 00 03 01 00 07


if everything is well configured, the audio route is activated now. the DOM checks now periodically (~10 seconds) every route. The PC has to reply to this command to confirm this route is still active. If the PC gives no response to this request, the DOM will deactivate this audio route after ~30 seconds.
Arrow lr.png COMMAND check route from [loc. 99. sc. 0] to [loc.103. sc. 0] mid[ 1] data: 09 94 2e 00 3d 63 01 00 01 00 05 09 94 2e 00 3d 26
Arrow rl.png RESPONSE check route from [loc.103. sc. 0] to [loc. 99. sc. 0] mid[ 1] data: 89 00 94 2e 00 3d


the PC deactivates now this route
Arrow rl.png COMMAND deactivate route from [loc.103. sc. 0] to [loc. 99. sc. 0] mid[ 1] data: 01 94 2e 00 3d
Arrow lr.png RESPONSE deactivate route from [loc. 99. sc. 0] to [loc.103. sc. 0] mid[ 1] data: 81 00 94 2e 00 3d 03 00 00 00 09 81 00 94 2e 00 3d 03 00 00 a7
Arrow lr.png RESPONSE destination busy info from [loc. 99. sc. 0] to [loc.255. ho. 0] mid[ 1] data: 87 00 00 00 00 63 01 00 01 00 04 87 00 00 00 0c