#include "config.h" #include #include #include #include #include #include "rpt.h" #include "fader.h" #ifdef OS_LINUX #include #endif #ifdef ARDUINO #include #include #endif fader::msgRef_t fader::_msgRefA[] = { { 0x0a, 88 }, // initial handshake { 0x0c, 4 }, // secondary handshake { 0x00, 8 }, // { 0x19, 1044 }, // 0x19 messages are variable length { 0x04, 4 }, // { 0xff, 0 } // end-of-list sentinel (both id and byteN are invalid) }; fader::fader( printCallback_t printCbFunc, const unsigned char faderMac[6], uint32_t faderInetAddr, euConCbFunc_t euconCbFunc, void* euconCbArg, physCtlCbFunc_t physCtlCbFunc, void* physCtlCbArg, unsigned ticksPerHeartBeat, unsigned chN ) : _printCbFunc(printCbFunc), _inetAddr(faderInetAddr), _tickN(0), _chArray(nullptr), _euconCbFunc(euconCbFunc), _euconCbArg(euconCbArg), _physCtlCbFunc(physCtlCbFunc), _physCtlCbArg(physCtlCbArg), _protoState(kWaitForHandshake_0_Id), _ticksPerHeartBeat(ticksPerHeartBeat), _msgTypeId(0xff), _msgByteIdx(0), _msgByteN(0), _mbi(0) { memcpy(_mac,faderMac,6); _chArray = new ch_t[chN]; _chN = chN; reset(); } fader::~fader() { delete[] _chArray; } void fader::reset() { _protoState = kWaitForHandshake_0_Id; _msgTypeId = 0xff; _msgByteIdx = 0; _msgByteN = 0; _mbi = 0; for(unsigned i=0; i<_chN; ++i) { _chArray[i].position = 0; _chArray[i].muteFl = false; _chArray[i].touchFl = false; } } fader::rc_t fader::receive_from_eucon( const void* buf, unsigned bufByteN ) { rc_t rc = kOkRC; const uint8_t* b = (const uint8_t*)buf; // current msg ptr const uint8_t* bend = b + bufByteN; // end of buffer ptr while(b7, value>0x3ff) uint8_t type = (msg[0] & 0x70) >> 4; uint8_t chan = (msg[0] & 0x0f); uint16_t value = msg[1]; value <<= 7; value += msg[2]; rpt(_printCbFunc,"T:%i Ch:%i V:%x\n",type,chan,value); switch( type ) { case kPhysTouchTId: _send_touch_to_eucon(chan,value != 0); break; case kPhysFaderTId: _send_fader_to_eucon(chan,value); break; case kPhysMuteTId: _send_mute_to_eucon(chan,value == 0); break; default: rpt(_printCbFunc,"Unknown physical ctl id."); } } void fader::_send_to_eucon( const void* buf, unsigned bufByteN ) { return _euconCbFunc(_euconCbArg,buf,bufByteN); } void fader::_send_response_0_to_eucon() { unsigned char buf[] = { 0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x02,0x03,0xfc,0x01,0x05, 0x06,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, // mac: offset 16 0x01,0x00, 0x00,0x00,0x00,0x00, // ip: offset 24 0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x03,0xff,0x00,0x30,0x08,0x00,0x00,0x80,0x00,0x40,0x01,0x01,0x00,0x00,0x00,0x00, 0x00,0x00 }; // set the mac address memcpy(buf+16,_mac,6); // set the 32 bit ip address memcpy((unsigned char *)(buf+24),(unsigned char*)&_inetAddr, 4); _send_to_eucon(buf,sizeof(buf)); } void fader::_send_response_1_to_eucon() { unsigned char buf[] = { 0x0d,0x00,0x00,0x00, 0x00,0x00,0x00,0x08 }; _send_to_eucon(buf,sizeof(buf)); } void fader::_send_heartbeat_to_eucon() { const unsigned char buf[] = { 0x03, 0x00, 0x00, 0x00 }; _send_to_eucon(buf,sizeof(buf)); } void fader::_send_fader_to_eucon( uint16_t chIdx, uint16_t pos ) { _chArray[chIdx].position = pos; if( _chArray[chIdx].touchFl ) { uint16_t buf[] = { htons(chIdx),htons(0), 0, htons(pos) }; _send_to_eucon(buf,sizeof(buf)); } } void fader::_send_touch_to_eucon( uint16_t chIdx, uint16_t touchFl ) { _chArray[chIdx].touchFl = touchFl; uint16_t buf[] = { htons(chIdx),htons(1),0, htons((uint16_t)touchFl) }; _send_to_eucon(buf,sizeof(buf)); } void fader::_send_mute_to_eucon( uint16_t chIdx, uint16_t muteFl ) { _chArray[chIdx].muteFl = muteFl; uint16_t buf[] = { htons(chIdx),htons(0x200),0, htons((uint16_t)(!muteFl)) }; _send_to_eucon(buf,sizeof(buf)); } uint16_t fader::_get_eucon_msg_byte_count( uint8_t msgTypeId, const uint8_t* b, const uint8_t* bend ) { if( msgTypeId == 0x19 ) { const uint16_t* u = (const uint16_t*)b; if( bend < (const uint8_t*)(u+4) ) { //_printCbFunc("0x19 short\n"); return 0; } uint16_t v = u[3]; return ntohs(v); } for(int i=0; _msgRefA[i].byteN != 0; ++i) if( msgTypeId == _msgRefA[i].id ) return _msgRefA[i].byteN; return 0; } void fader:: _send_to_phys_control( uint8_t ctlTypeId, uint8_t ch, uint16_t value ) { uint8_t msg[3]; msg[0] = 0x80 + (ctlTypeId << 4) + (ch); // status byte always has high bit set msg[1] = (uint8_t)((value & 0x3f80) >> 7); // get high 7 bits of value (high bit is always cleared) msg[2] = (uint8_t)(value & 0x007f); // get low 7 bits of value (high bit is always cleared) _physCtlCbFunc( _physCtlCbArg, msg, sizeof(msg) ); } // called when a new msg is received, b[0] is the msg type id void fader::_on_eucon_recv_msg_complete( const uint8_t typeId ) { switch( typeId ) { case 0x0a: if( _protoState == kWaitForHandshake_0_Id ) { _printCbFunc("HS 0 "); _send_response_0_to_eucon(); // send [ 0x0b ... ] _protoState = kWaitForHandshake_Tick_Id; } break; case 0x0c: //rpt(_printCbFunc,"HB\n"); break; case 0x00: { const uint16_t* u = (const uint16_t*)_msg; uint8_t ch = _msg[1]; if( ch < 8 ) { switch( ntohs(u[1]) ) { case 0: _chArray[ch].position = ntohs(u[3]); //rpt(_printCbFunc,"F: %2i %4i \n",(int)_msg[1],ntohs(u[3])); _send_to_phys_control(kPhysFaderTId,ch,ntohs(u[3])); break; case 0x201: _chArray[ch].muteFl = ntohs(u[3]); //rpt(_printCbFunc,"M: %2i %4i \n",(int)_msg[1],ntohs(u[3])); _send_to_phys_control(kPhysMuteTId,ch,ntohs(u[3])); break; } } } break; case 0x04: //rpt(_printCbFunc,"HB:\n"); break; case 0x19: //rpt(_printCbFunc,"Skip:\n"); break; default: rpt(_printCbFunc,"Unknown msg type."); } // Any msg will trigger change of state from // kWaitForHandshake_1_Id to kWaitForHeartBeat_Id if( _protoState == kWaitForHandshake_1_Id ) { _printCbFunc("HS 1\n "); _send_response_1_to_eucon(); //send [ 0x0d, .... ] _protoState = kWaitForHeartBeat_Id; } }