From 9e2633ff82b96da60e0dd143192ae3ac203b610b Mon Sep 17 00:00:00 2001 From: surenyi Date: Fri, 27 Nov 2015 15:12:42 +0800 Subject: [PATCH] refactor code Signed-off-by: surenyi --- AlarmProvider.h | 10 -- AudioBridge.cpp | 170 -------------------------- AudioBridge.h | 95 --------------- AudioProvider.h | 23 ---- CRC32.h | 17 --- CharConv.cpp | 85 ------------- CharConv.h | 24 ---- IdMapper.cpp => IdMapper.c | 6 +- IdMapper.h | 7 +- Lan.cpp | 200 ------------------------------- PTTProvider.h | 15 --- Runtime.cpp | 186 ----------------------------- Runtime.h | 52 -------- Timer.cpp | 35 ------ Timer.h | 18 --- Udp.h | 28 ----- UdpEvent.cpp | 41 ------- UdpEvent.h | 33 ----- UdpReadable.cpp | 26 ---- UdpReadable.h | 23 ---- Wan.cpp | 112 ----------------- char_conv.c | 124 +++++++++++++++++++ char_conv.h | 11 ++ codec.c | 237 ++++++++++++++++++++++++++++++++++++ codec.h | 77 ++++++++++++ CRC32.cpp => crc.c | 28 ++--- crc.h | 7 ++ lan.c | 239 +++++++++++++++++++++++++++++++++++++ lan.h | 117 ++++++++++++++++++ Log.cpp => log.c | 12 +- log.h | 7 ++ main.c | 10 ++ main.cpp | 15 --- makefile | 10 +- runtime.c | 174 +++++++++++++++++++++++++++ runtime.h | 43 +++++++ timer.c | 45 +++++++ timer.h | 17 +++ Udp.cpp => udp.c | 144 ++++++++++++---------- udp.h | 18 +++ udp_readable.c | 33 +++++ udp_readable.h | 17 +++ wan.c | 181 ++++++++++++++++++++++++++++ Wan.h => wan.h | 43 +++---- 44 files changed, 1475 insertions(+), 1340 deletions(-) delete mode 100644 AlarmProvider.h delete mode 100644 AudioBridge.cpp delete mode 100644 AudioBridge.h delete mode 100644 AudioProvider.h delete mode 100644 CRC32.h delete mode 100644 CharConv.cpp delete mode 100644 CharConv.h rename IdMapper.cpp => IdMapper.c (80%) delete mode 100644 Lan.cpp delete mode 100644 PTTProvider.h delete mode 100644 Runtime.cpp delete mode 100644 Runtime.h delete mode 100644 Timer.cpp delete mode 100644 Timer.h delete mode 100644 Udp.h delete mode 100644 UdpEvent.cpp delete mode 100644 UdpEvent.h delete mode 100644 UdpReadable.cpp delete mode 100644 UdpReadable.h delete mode 100644 Wan.cpp create mode 100644 char_conv.c create mode 100644 char_conv.h create mode 100644 codec.c create mode 100644 codec.h rename CRC32.cpp => crc.c (51%) create mode 100644 crc.h create mode 100644 lan.c create mode 100644 lan.h rename Log.cpp => log.c (59%) create mode 100644 log.h create mode 100644 main.c delete mode 100644 main.cpp create mode 100644 runtime.c create mode 100644 runtime.h create mode 100644 timer.c create mode 100644 timer.h rename Udp.cpp => udp.c (50%) create mode 100644 udp.h create mode 100644 udp_readable.c create mode 100644 udp_readable.h create mode 100644 wan.c rename Wan.h => wan.h (55%) diff --git a/AlarmProvider.h b/AlarmProvider.h deleted file mode 100644 index a0528c4..0000000 --- a/AlarmProvider.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __ALARM_PROVIDER_H__ -#define __ALARM_PROVIDER_H__ - -class AlarmProvider { -public: - void onAlarm(const char *str, int len); -}; - -#endif - diff --git a/AudioBridge.cpp b/AudioBridge.cpp deleted file mode 100644 index f1f527d..0000000 --- a/AudioBridge.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include -#include -#include -#include "UdpEvent.h" -#include "Log.h" -#include "Wan.h" -#include "Lan.h" -#include "IdMapper.h" -#include "AudioBridge.h" - -class AudioUpEvent : public UdpEvent { - private: - AudioBridge *_bge; - public: - AudioUpEvent(Udp u, AudioBridge *_b) : UdpEvent(u), _bge(_b){} - void onEvent(int /* fd */, short what) - { - uint8_t buf[1500] = {0}; - - /* send to uplink */ - if (what & UDP_READ) { - int n = _udp.recv(buf, sizeof buf); - if (n > 0) - _bge->onUpComplete(buf, n); - } - } -}; - -class AudioDownEvent : public UdpEvent { - private: - AudioBridge *_bge; - public: - AudioDownEvent(Udp u, AudioBridge *_b) : UdpEvent(u), _bge(_b){} - void onEvent(int /* fd */, short what) - { - if (what & UDP_READ) { - uint8_t buf[700] = {0}; - int n = _udp.recv(buf, sizeof buf); - if (n > 0) - _bge->onDownComplete(buf, n); - } - /* send to downlink */ - } -}; - -AudioBridge::AudioBridge() -:_uplink(0), _downlink(0), _downProvider(0), _upProvider(0), _audioEncType(AUDIO_ENC_ALL) -{ - _encSeq = 0; - _decSeq = 0; -} - -uint8_t AudioBridge::getCheckNum(uint8_t *buf, int len) -{ - uint32_t sum = 0; - - for (int i = 0; i < len; ++i) { - sum += buf[i]; - } - - return (sum & 0xff); -} - -void AudioBridge::onUpAudio(struct MsgAudio *audio) -{ - memset(&_encBuf, 0, sizeof _encBuf); - - _encBuf.id1 = 0xAC; - _encBuf.id2 = 0x93; - _encBuf.id3 = 0x27; - _encBuf.id4 = 0x21; - _encBuf.swId = 0xB1; - _encBuf.fromId = 0xD8; - _encBuf.toId = 0xFF; - _encBuf.toSwId = 0xE2; - _encBuf.origPosId = IdMapper::getMappedWanId(audio->sender); - _encBuf.encType = _audioEncType; - _encBuf.contentId = 0xED; - _encBuf.flyType = 0; - _encBuf.flyId = 0; - - /* XXX: here need to convert */ - size_t len = audio->payloadLen; - if (len > sizeof _encBuf.payload) - len = sizeof _encBuf.payload; - memcpy(_encBuf.payload, audio->payload, len); - - _encBuf.timeStamp = htonl(time(NULL)); - _encBuf.seqNum = htonl(++_encSeq); - _encBuf.checkNum = getCheckNum((uint8_t *)&_encBuf, sizeof _encBuf - 2); - _encBuf.id5 = 0x14; - - _uplink->getUdp().send(&_encBuf, sizeof _encBuf); -} - -void AudioBridge::onDownAudio(struct WanAudioType *wat) -{ - memset(&_decBuf, 0, sizeof _decBuf); - - _decBuf.id1 = 0xAC; - _decBuf.id2 = 0x93; - _decBuf.id3 = 0x27; - _decBuf.id4 = 0x21; - _decBuf.swId = 0xB1; - _decBuf.origSwId = 0xD8; - _decBuf.toId = 0xFF; - _decBuf.toSwId = 0xE2; - _decBuf.origPosId = 0xB1; - _decBuf.encType = _audioEncType; - _decBuf.contentId = 0xED; - _decBuf.flyType = wat->apType; - _decBuf.flyId = wat->apId; - - memcpy(_decBuf.payload, wat->mgrAudio, 6); - memcpy(_decBuf.auxPayload, wat->auxAudio, 6); - _decBuf.timeStamp = htonl(time(NULL)); - _decBuf.seqNum = htonl(++_decSeq); - _decBuf.checkNum = getCheckNum((uint8_t *)&_decBuf, sizeof _decBuf - 2); - _decBuf.id5 = 0x14; - _downlink->getUdp().send((uint8_t *)&_decBuf, sizeof _decBuf); -} - -int AudioBridge::__makeLink(Udp & _u, const char *bridge_ip, int bridge_port, const char *local_ip, int local_port) -{ - if (_u.open() < 0) { - Log.printf("'%s[%d]: can't create socket\n", __FILE__, __LINE__); - return -1; - } - if (_u.bind(local_ip, local_port) < 0) { - Log.printf("'%s[%d]: can't bind [%s:%d] socket (%d: %s)\n", __FILE__, __LINE__, local_ip, local_port, errno, strerror(errno)); - _u.close(); - return -2; - } - if (_u.connect(bridge_ip, bridge_port) < 0) { - Log.printf("'%s[%d]: can't connect [%s:%d] socket\n", __FILE__, __LINE__, local_ip, local_port); - _u.close(); - return -3; - } - return 0; -} - -int AudioBridge::begin(const char *bridge_ip, int bridge_port, const char *local_ip, int down_port, int up_port) -{ - Udp d, u; - - if (__makeLink(d, bridge_ip, bridge_port, local_ip, down_port) < 0) { - return -1; - } - - if (__makeLink(u, bridge_ip, bridge_port, local_ip, up_port) < 0) { - d.close(); - return -2; - } - _downlink = new AudioDownEvent(d, this); - _uplink = new AudioUpEvent(u, this); - return 0; -} - -void AudioBridge::onUpComplete(uint8_t *data, int len) -{ - if (_upProvider) - _upProvider->onComplete(data, len); -} - -void AudioBridge::onDownComplete(uint8_t *data, int len) -{ - if (_downProvider) - _downProvider->onComplete(data, len); -} - diff --git a/AudioBridge.h b/AudioBridge.h deleted file mode 100644 index 1b64a1e..0000000 --- a/AudioBridge.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef __AUDIO_BRIDGE_H__ -#define __AUDIO_BRIDGE_H__ - -#include - -#include "AudioProvider.h" -#include "UdpReadable.h" - -#define AUDIO_ENC_ALL 0x00 -#define AUDIO_ENC_10 0x01 -#define AUDIO_ENC_712 0x02 - -#define AUDIO_ENC_PKT_LEN (666) -#define AUDIO_DEC_PKT_LEN (64) - -struct AudioEncType { - uint8_t id1; - uint8_t id2; - uint8_t id3; - uint8_t id4; - uint16_t resv0; - uint8_t swId; - uint8_t fromId; - uint8_t toId; - uint8_t toSwId; - uint8_t origPosId; - uint8_t resv1; - uint8_t encType; - uint8_t contentId; - uint8_t flyType; - uint8_t flyId; - uint8_t payload[640]; - uint32_t timeStamp; - uint32_t seqNum; - uint8_t checkNum; - uint8_t id5; -} __attribute__((packed)); - -struct AudioDecInType { - uint8_t id1; - uint8_t id2; - uint8_t id3; - uint8_t id4; - uint16_t resv0; - uint8_t swId; - uint8_t origSwId; - uint8_t toId; - uint8_t toSwId; - uint8_t origPosId; - uint8_t resv1; - uint8_t encType; - uint8_t contentId; - uint8_t flyType; - uint8_t flyId; - uint8_t payload[6]; - uint8_t auxPayload[6]; - uint8_t resv2[26]; - uint32_t timeStamp; - uint32_t seqNum; - uint8_t checkNum; - uint8_t id5; -} __attribute((packed)); - -class UdpEvent; -class Udp; -class AudioBridge : public AudioUpProvider, public AudioDownProvider { - private: - UdpEvent *_uplink; - UdpEvent *_downlink; - AudioCompleteProvider *_downProvider; - AudioCompleteProvider *_upProvider; - uint8_t _audioEncType; - AudioEncType _encBuf; - uint32_t _encSeq; - AudioDecInType _decBuf; - uint32_t _decSeq; - int __makeLink(Udp & _u, const char *brige_ip, int bridge_port, const char *local_ip, int local_port); - uint8_t getCheckNum(uint8_t *buf, int len); - public: - AudioBridge(); - virtual void onUpAudio(struct MsgAudio *); - virtual void onDownAudio(struct WanAudioType *); - - int begin(const char *bridge_ip, int bridge_port, const char *local_ip, int down_port, int up_port); - - void setAudioEncType(uint8_t type) { _audioEncType = type;} - void setUpCompleteProvider(AudioCompleteProvider *_p) {_upProvider = _p;} - void setDownCompleteProvider(AudioCompleteProvider *_p) {_downProvider = _p;} - - void onDownComplete(uint8_t *data, int len); - void onUpComplete(uint8_t *data, int len); -}; - -#endif - diff --git a/AudioProvider.h b/AudioProvider.h deleted file mode 100644 index 6baa3a1..0000000 --- a/AudioProvider.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __AUDIO__PROVIDER_H__ -#define __AUDIO__PROVIDER_H__ - -struct MsgAudio; -struct WanAudioType; - -class AudioUpProvider { -public: - virtual void onUpAudio(MsgAudio * audio) = 0; -}; - -class AudioDownProvider { -public: - virtual void onDownAudio(struct WanAudioType *) = 0; -}; - -class AudioCompleteProvider { -public: - virtual void onComplete(uint8_t *buf, int len) = 0; -}; - -#endif - diff --git a/CRC32.h b/CRC32.h deleted file mode 100644 index 4941b3e..0000000 --- a/CRC32.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __CRC32_H__ -#define __CRC32_H__ - -#include - -class Crc32 { -private: - unsigned int crc_table[256]; - void init(); - uint32_t doCrc(uint32_t crc,unsigned char *buffer, unsigned int size); -public: - Crc32(); - uint32_t crc(uint8_t *data, int len); -}; - -#endif - diff --git a/CharConv.cpp b/CharConv.cpp deleted file mode 100644 index 1c2d825..0000000 --- a/CharConv.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include "CharConv.h" -#include "UdpEvent.h" -#include "Runtime.h" -#include "Lan.h" -#include "Log.h" - -#define LOIFADDR "127.0.0.1" - -void CharConv::isReadable(Udp &u) -{ - uint8_t buf[1560] = {0}; - int len; - - Log.printf("char readable\n"); - if ((len = u.recv(buf, sizeof buf)) <= 0) - return; - Log.printf("char conv recv: %d bytes\n", len); - /* XXX : packetizing ... */ - Runtime.getLan().send(buf, len); -} - -int CharConv::begin(int to_port, int from_port) -{ - Udp u; - - if (u.open() < 0) { - Log.printf("'%s[%d]: can't create socket\n", __FILE__, __LINE__); - return -1; - } - - if (u.bind(LOIFADDR, from_port) < 0) { - Log.printf("'%s[%d]: can't bind [%s:%d] socket (%d: %s)\n", __FILE__, __LINE__, LOIFADDR, from_port, errno, strerror(errno)); - u.close(); - return -2; - } - if (u.connect(LOIFADDR, to_port) < 0) { - Log.printf("'%s[%d]: can't connect [%s:%d] socket\n", __FILE__, __LINE__, LOIFADDR, to_port); - u.close(); - return -3; - } - - UdpReadable::begin(u); - _cd = iconv_open("GB2312", "UTF-8"); - if (_cd == (iconv_t)-1) { - Log.printf("can't crate iconv conventer\n"); - } - return 0; -} - -void CharConv::onAlarm(const char *str, int len) -{ - uint8_t buf[1500] = {0}; - int idx = 0; - - Log.printf("alarm: %d, %s\n", len, str); - - buf[idx++] = 0x68; - buf[idx++] = 0x00; - buf[idx++] = 0x00; - buf[idx++] = 0x80; - buf[idx++] = len & 0xff; - buf[idx++] = (len >> 8) & 0xff; - memcpy(buf + idx, str, len); - idx += len; - uint32_t cs = _crc.crc((uint8_t *)str, len); - buf[idx++] = cs & 0xff; - buf[idx++] = (cs >> 8) & 0xff; - buf[idx++] = (cs >> 16) & 0xff; - buf[idx++] = (cs >> 24) & 0xff; - - int n = _udp.send(buf, idx); - Log.printf("conv sending: %d bytes\n", n); -} - -void CharConv::end() -{ - if (_cd != (iconv_t)-1) { - iconv_close(_cd); - _cd = (iconv_t)-1; - } - _udp.close(); -} - diff --git a/CharConv.h b/CharConv.h deleted file mode 100644 index 269cfef..0000000 --- a/CharConv.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __CHAR_CONV_H__ -#define __CHAR_CONV_H__ - -#include -#include "AlarmProvider.h" -#include "UdpReadable.h" -#include "CRC32.h" - -class CharConv : public AlarmProvider, public UdpReadable { -private: - Crc32 _crc; - iconv_t _cd; -public: - int begin(int to_port, int from_port); - void onAlarm(const char *str, int len); - virtual void isReadable(Udp &u); - void end(); - ~CharConv() { - end(); - } -}; - -#endif - diff --git a/IdMapper.cpp b/IdMapper.c similarity index 80% rename from IdMapper.cpp rename to IdMapper.c index 0e36048..56b2943 100644 --- a/IdMapper.cpp +++ b/IdMapper.c @@ -1,4 +1,4 @@ -#include "Lan.h" +#include "lan.h" #include "IdMapper.h" struct Idmap { @@ -15,7 +15,7 @@ static struct Idmap idmap[NOOFTERMS] = { {0xFD, 0x06} }; -uint8_t IdMapper::getMappedWanId(uint8_t id) +uint8_t getMappedWanId(uint8_t id) { for (int i = 0; i < NOOFTERMS; ++i) { if (idmap[i].lanId == id) { @@ -25,7 +25,7 @@ uint8_t IdMapper::getMappedWanId(uint8_t id) return 0; } -uint8_t IdMapper::getMappedLanId(uint8_t id) +uint8_t getMappedLanId(uint8_t id) { for (int i = 0; i < NOOFTERMS; ++i) { if (idmap[i].wanId == id) { diff --git a/IdMapper.h b/IdMapper.h index 7b8c51b..f553b71 100644 --- a/IdMapper.h +++ b/IdMapper.h @@ -2,13 +2,10 @@ #define __IDMAPPER_H__ #include -class IdMapper { -public: /* convert lan id to wan id */ - static uint8_t getMappedWanId(uint8_t id); +uint8_t getMappedWanId(uint8_t id); /* convert wna id to lan id */ - static uint8_t getMappedLanId(uint8_t id); -}; +uint8_t getMappedLanId(uint8_t id); #endif diff --git a/Lan.cpp b/Lan.cpp deleted file mode 100644 index 5848c40..0000000 --- a/Lan.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#include -#include -#include "IdMapper.h" -#include "UdpEvent.h" -#include "AudioBridge.h" -#include "Lan.h" -#include "Log.h" - -#define LAN_PKT_MIN_LEN (16) -#define LAN_PKT_MAX_LEN (256) - -int Lan::begin(const char *group_addr, int port, const char *local_if) -{ - Udp udp; - -#if 0 - Log.printf("struct MsgCmd: %d\n", sizeof (struct MsgCmd)); - Log.printf("struct MsgTermStatus: %d\n", sizeof (struct MsgTermStatus)); - Log.printf("struct MsgAudio: %d\n", sizeof (struct MsgAudio)); - Log.printf("struct MsgAlarm: %d\n", sizeof (struct MsgAlarm)); -#endif - - if (udp.open() < 0) { - Log.printf("'%s[%d]: can't create Lan socket\n", __func__, __LINE__); - return -1; - } - Log.printf("local: %s, %s, %d\n", local_if, group_addr, port); - if (udp.bind(local_if, port) < 0) { - Log.printf("'%s[%d]: can't bind Lan socket\n", __func__, __LINE__); - udp.close(); - return -2; - } - - if (udp.connect(group_addr, port) < 0) { - Log.printf("'%s[%d]: can't connect Lan socket\n", __func__, __LINE__); - udp.close(); - return -3; - } - - UdpReadable::begin(udp); - _myseq = 0; - return 0; -} - -void Lan::doCmd(uint8_t *buf, int len) -{ - struct MsgCmd hdr, *sdp; - struct MsgTermStatus *mts; - uint8_t out; - uint16_t cmd; - - sdp = (struct MsgCmd *)(buf); - hdr = *sdp; - cmd = ntohs(hdr.msgCmd); -// Log.printf("Lan cmd [%02x]\n", cmd); - switch (cmd) { - case MSG_CMD_HANDSHAKE: - hdr.sender = sdp->recver; - hdr.recver = sdp->sender; - hdr.msgCmd = htons(MSG_RES_HANDSHAKE); -#if 0 - do { - uint8_t *dp; - dp = (uint8_t *)&hdr; - for (int x= 0; x < 12; ++x) { - Log.printf("%02x ", dp[x]); - } - Log.printf("\n"); - } while (0); -#endif - send(&hdr, sizeof hdr); - len -= sizeof hdr; - buf += sizeof hdr; - /* 6 x 4 bytes: - * 0 1 2 3 - * id downlink ptt alarm - */ - while (len > (int)sizeof (*mts)) { - mts = (struct MsgTermStatus *)buf; - out = IdMapper::getMappedWanId(mts->termId); - if (out > 0) { - _provider->onStatus(out, mts->isAlarm); - } - len -= sizeof (*mts); - buf += sizeof (*mts); - } - break; - case MSG_CMD_PTTON: - out = IdMapper::getMappedWanId(hdr.sender); - if (out > 0) { - _provider->onPTT(this, &hdr, out, true); - } - break; - case MSG_CMD_PTTOFF: - out = IdMapper::getMappedWanId(hdr.sender); - if (out > 0) { - _provider->onPTT(this, &hdr, out, false); - } - break; - } -} - - -void Lan::doAudio(uint8_t *buf, int len) -{ - struct MsgAudio *laph; - - if (len < (int)(sizeof *laph)) - return; - - laph = (struct MsgAudio *)(buf); - laph->payloadLen = ntohl(laph->payloadLen); - if (len < (int)(sizeof *laph + laph->payloadLen)) { - Log.printf("audio length too small, total: %d, payload: %d\n", len, laph->payloadLen); - return; - } - - Log.printf("recver< %d >: %x, sender: %x, mode: %d, recvChannel: %d, sendChannel: %d\n", - laph->payloadLen, laph->recver, laph->sender, laph->mode, laph->recvChannel, laph->sendChannel); - _audioUp->onUpAudio(laph); -} - -void Lan::isReadable(Udp & _u) -{ - uint8_t buf[LAN_PKT_MAX_LEN] = {0}; - int len; - - if ((len = _u.recv(buf, sizeof buf)) < LAN_PKT_MIN_LEN) - return; -#if 0 - do { - Log.printf("Lan: %d bytes\n", len); - for (int x = 0; x < len; ++x) { - Log.printf("%02x%c", buf[x], ((x + 1) % 16) ? ' ' : '\n'); - } - Log.printf("\n"); - } while (0); -#endif - switch (buf[0]) { - case MSG_TYPE_CMD: - doCmd(buf, len); - break; - case MSG_TYPE_AUDIO: - doAudio(buf, len); - break; - case MSG_TYPE_ALARM: - break; - } -} - -void Lan::onComplete(uint8_t *buf, int len) -{ - struct AudioEncType *aet; - struct MsgAudio *ma; - uint8_t msg[MSG_AUDIO_LEN] = {0}; - - if (len < (int)(sizeof *aet)) { - Log.printf("Audio too short.\n"); - return; - } - - ma = (struct MsgAudio *)(msg); - aet = (struct AudioEncType *)(buf); - ma->type = MSG_TYPE_AUDIO; - ma->recver = 0x19; - ma->sender = 0x07; - ma->swid = 0xB1; - ma->seqNum = htonl(++_myseq); - ma->payloadLen = 160; - - /*XXX: transcode aet->payload */ - memcpy(ma->payload, aet->payload, ma->payloadLen); - - send(msg, sizeof msg); -} - -int Lan::onResponse(int resp_type, struct MsgCmd *hdr, int status) -{ - struct MsgCmd pkt; - - pkt = *hdr; - pkt.recver = hdr->sender; - pkt.sender = hdr->recver; - switch (resp_type) { - case RESP_PTT_ON: - if (status == RESP_PTT_OK) { - pkt.msgCmd = htons(MSG_RES_PTTON); - } else { - pkt.msgCmd = htons(MSG_REFUSE_PTTON); - } - break; - case RESP_PTT_OFF: - pkt.msgCmd = htons(MSG_RES_PTTOFF); - break; - } - send(&pkt, sizeof pkt); - - return 0; -} - diff --git a/PTTProvider.h b/PTTProvider.h deleted file mode 100644 index dcc3b36..0000000 --- a/PTTProvider.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __PTTPROVIDER_H__ -#define __PTTPROVIDER_H__ - -#include - -class Lan; -struct MsgCmd; -class PTTProvider { - public: - virtual void onPTT(Lan *, struct MsgCmd *hdr, uint8_t posId, bool on) = 0; - virtual void onStatus(uint8_t id, uint8_t status) = 0; -}; - -#endif - diff --git a/Runtime.cpp b/Runtime.cpp deleted file mode 100644 index d377132..0000000 --- a/Runtime.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include -#include -#include -#include "Runtime.h" -#include "Log.h" -#include "Udp.h" -#include "Timer.h" - -#define LAN_IF "eth0" -#define LAN_FROM "192.168.9.25" -#define LAN_PORT 5600 - -#define BGE_IP "192.168.9.19" -#define BGE_PORT 6419 -#define BGE_UP_PORT 6402 -#define BGE_DOWN_PORT 6400 - -/* - * Please disable rp_filter - * edit /etc/sysctl.conf - * - * net.ipv4.conf.default.rp_filter = 0 - * net.ipv4.conf.all.rp_filter = 0 - * - * add route for eth1 - * route add -net 192.168.31.0/24 dev eth1 - */ -#if 1 -#define WAN_IF "eth1" -#define WAN_GROUP "225.0.0.5" -#define WAN_GROUP_PORT 8300 -#define WAN_STATUS_PORT 8100 -#else -#define WAN_IF "eth0" -#define WAN_GROUP "224.0.0.24" -#define WAN_GROUP_PORT 8300 -#define WAN_STATUS_PORT 5100 -#endif - -Runtime::Runtime() -{ - struct event_config *config; - - _lan_if = (char *)LAN_IF; - _lan_grp_addr = (char *)LAN_FROM; - _lan_grp_port = LAN_PORT; - - _bge_ip = (char *)BGE_IP; - _bge_port = BGE_PORT; - _up_port = BGE_UP_PORT; - _down_port = BGE_DOWN_PORT; - - _wan_if = (char *)WAN_IF; - _wan_grp_addr = (char *)WAN_GROUP; - _wan_grp_port = WAN_GROUP_PORT; - _wan_status_port = WAN_STATUS_PORT; - - config = event_config_new(); - event_config_avoid_method(config, "select"); - event_config_require_features(config, EV_FEATURE_ET); - _evbase = event_base_new_with_config(config); - event_config_free(config); -} - -int Runtime::loop() -{ - return event_base_dispatch(_evbase); -} - -void Runtime::printHelp() -{ - fprintf(stderr, "usage: cmd [option], options as:\n\t" - "--lanif, -l: set lan ethx interface, eg: \"ethx\"\n\t" - "--landest, -g: set lan multicast address, eg: \"192.168.9.25\"\n\t" - "--lanport, -p: set lan multicast port, eg: 5600\n\t" - "--wanif, -w: set lan ethx interface, eg: \"ethx\"\n\t" - "--wangrp, -r: set lan multicast address, eg: \"255.0.0.5\"\n\t" - "--wanport, -t: set lan multicast port, eg: 5600\n\t" - "--help, -h: print this message.\n"); -} - -void Runtime::parseArgs(int argc, char *argv[]) -{ - int c; - static struct option options[] = { - {"lanif", required_argument, NULL, 'l'}, - {"landest", required_argument, NULL, 'g'}, - {"lanport", required_argument, NULL, 'p'}, - {"wanif", required_argument, NULL, 'w'}, - {"wangrp", required_argument, NULL, 'r'}, - {"wanport", required_argument, NULL, 't'}, - {"wanstport", required_argument, NULL, 'o'}, - {"help", no_argument, NULL, 'h'}, - {NULL, 0, NULL, 0} - }; - - while ((c = getopt_long(argc, argv, "l:g:p:w:r:t:o:h", options, NULL)) != -1) { - switch (c) { - case 'l': - _lan_if = optarg; - break; - case 'g': - _lan_grp_addr = optarg; - break; - case 'p': - _lan_grp_port = atoi(optarg); - break; - case 'w': - _wan_if = optarg; - break; - case 'r': - _wan_grp_addr = optarg; - case 't': - _wan_grp_port = atoi(optarg); - break; - case 'o': - _wan_status_port = atoi(optarg); - break; - case 'h': - printHelp(); - exit(0); - } - } -} - -class AlarmTimer : public Timer { -private: - CharConv *_c; - int count; -public: - AlarmTimer(CharConv *c) : _c(c), count(0){} - virtual void onTimer() - { - char buf[128]; - snprintf(buf, sizeof buf, "数量这么多数据还是不错"); - _c->onAlarm(buf, strlen(buf)); - } -}; - -void Runtime::begin() -{ - char local_if[64] = {0}; - char wan_if[64] = {0}; - - Log.begin(); - - Udp::getip(_lan_if, local_if, sizeof local_if); - if (_lan.begin(_lan_grp_addr, _lan_grp_port, local_if) < 0) { - Log.printf("lan initialize failed.\n"); - exit(-1); - } - - if (_abge.begin(_bge_ip, _bge_port, local_if, _down_port, _up_port) < 0) { - Log.printf("audio bridge initialize failed.\n"); - exit(-2); - } - - Udp::getip(_wan_if, wan_if, sizeof wan_if); - if (_wan.begin(_wan_grp_addr, _wan_grp_port, wan_if, _wan_status_port) < 0) { - Log.printf("wan initialize failed.\n"); - exit(-3); - } - - if (_conv.begin(6801, 6802) < 0) { - Log.printf("char convter initiazlie failed.\n"); - exit(-4); - } - -#if 1 - static AlarmTimer at(&_conv); - at.begin(); - at.active(1000); -#endif - _abge.setDownCompleteProvider(&_lan); - _abge.setUpCompleteProvider(&_wan); - - _lan.setAudioUpProvider(&_abge); - _wan.setAudioDownProvider(&_abge); - - _lan.setPTTProvider(&_wan); - - _wan.setAlarmProvider(&_conv); -} - -class Runtime Runtime; - diff --git a/Runtime.h b/Runtime.h deleted file mode 100644 index 3bb414b..0000000 --- a/Runtime.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __RUNTIME_H____ -#define __RUNTIME_H____ - -#include -#include "Lan.h" -#include "Wan.h" -#include "AudioBridge.h" -#include "CharConv.h" - -class Runtime { -private: - struct event_base *_evbase; - - /* lan config */ - Lan _lan; - char *_lan_if; - char *_lan_grp_addr; - int _lan_grp_port; - - /* audio bridge */ - AudioBridge _abge; - char *_bge_ip; - int _bge_port; - int _up_port; - int _down_port; - - /* Wan */ - Wan _wan; - char *_wan_if; - char *_wan_grp_addr; - int _wan_grp_port; - int _wan_status_port; - - CharConv _conv; - - void printHelp(); -public: - Runtime(); - - void parseArgs(int argc, char *argv[]); - - void begin(); - - Lan & getLan() { return _lan;} - - struct event_base *getEvBase() const { return _evbase;} - int loop(); -}; - -extern class Runtime Runtime; -#endif - diff --git a/Timer.cpp b/Timer.cpp deleted file mode 100644 index fc429d1..0000000 --- a/Timer.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "Timer.h" -#include "Log.h" -#include "Runtime.h" - -void Timer::__helper(int , short, void *arg) -{ - Timer *t = static_cast(arg); - t->onTimer(); -} - -void Timer::onTimer() -{ - Log.printf("dummy timer\n"); -} - -void Timer::begin() -{ - event_assign(&_evt, Runtime.getEvBase(), -1, EV_TIMEOUT | EV_PERSIST, __helper, this); -} - -void Timer::active(int ms) -{ - struct timeval tv; - - tv.tv_sec = ms / 1000; - tv.tv_usec = ms % 1000; - - event_add(&_evt, &tv); -} - -void Timer::deactive() -{ - event_del(&_evt); -} - diff --git a/Timer.h b/Timer.h deleted file mode 100644 index 1edc860..0000000 --- a/Timer.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __ETIMER_H__ -#define __ETIMER_H__ - -#include -#include -class Timer { -private: - struct event _evt; - static void __helper(int fd, short what, void *arg); -public: - void begin(); - void active(int us); - void deactive(); - virtual void onTimer(); -}; - -#endif - diff --git a/Udp.h b/Udp.h deleted file mode 100644 index 401ad1e..0000000 --- a/Udp.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __UDP_H___ -#define __UDP_H___ - -#include -#include -#include -#include - -class Udp { - protected: - int sock; - struct sockaddr_in destAddr; - bool isMcast; - public: - Udp(); - Udp(const Udp &_u) { sock = _u.sock;} - int getFd() { return sock;} - int open(); - int send(const void *buf, int len); - int recv(void *buf, int len); - int openMulticast(const char *group, int port, const char *local); - int bind(const char *ip_dot, int port); - int connect(const char *to, int to_port); - int close(); - static int getip(const char *ethx, char *ip_dot, int len); -}; -#endif - diff --git a/UdpEvent.cpp b/UdpEvent.cpp deleted file mode 100644 index d8879bd..0000000 --- a/UdpEvent.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "Udp.h" -#include "UdpEvent.h" -#include "Log.h" -#include "Runtime.h" - -UdpEvent::~UdpEvent() -{ - if (_evt) { - end(); - } - _udp.close(); -} - -void UdpEvent::__helper(int fd, short what, void *arg) -{ - UdpEvent *ue = static_cast(arg); - - ue->onEvent(fd, what); -} - -void UdpEvent::end() -{ - event_del(_evt); - event_free(_evt); - _evt = NULL; -} - -int UdpEvent::begin(int flag, bool oneshot) -{ - if (!oneshot) - flag |= EV_PERSIST; - - Log.printf("flag: %02x, fd: %d\n", flag, _udp.getFd()); - _evt = event_new(Runtime.getEvBase(), _udp.getFd(), flag, __helper, this); - if (_evt) { - event_add(_evt, NULL); - return 0; - } - return -1; -} - diff --git a/UdpEvent.h b/UdpEvent.h deleted file mode 100644 index ca9a2e2..0000000 --- a/UdpEvent.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __UDPEVENT_H__ -#define __UDPEVENT_H__ - -#include - -#include "Udp.h" - -class UdpEvent { - protected: - Udp _udp; - struct event *_evt; - private: - static void __helper(int fd, short what, void *arg); - public: - enum {UDP_READ = EV_READ, UDP_WRITE = EV_WRITE}; - - UdpEvent() : _evt(0){} - UdpEvent(Udp _u) : _udp(_u), _evt(0) {} - - int begin(Udp udp, int type, bool onshot = false); - - int begin(int type, bool oneshot = false); - void end(); - - Udp & getUdp(){return _udp;} - - virtual void onEvent(int , short) = 0; - - virtual ~UdpEvent(); -}; - -#endif - diff --git a/UdpReadable.cpp b/UdpReadable.cpp deleted file mode 100644 index 946b91a..0000000 --- a/UdpReadable.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "Udp.h" -#include "UdpReadable.h" -#include "Log.h" -#include "Runtime.h" - -void UdpReadable::__helper(int /* fd */, short what, void *arg) -{ - UdpReadable *p = static_cast(arg); - if (what & EV_READ) { - p->isReadable(p->_udp); - } -} - -int UdpReadable::begin(const Udp &udp) -{ - _udp = udp; - event_assign(&_evt, Runtime.getEvBase(), _udp.getFd(), EV_READ | EV_PERSIST, __helper, this); - event_add(&_evt, NULL); - return 0; -} - -void UdpReadable::end() -{ - event_del(&_evt); -} - diff --git a/UdpReadable.h b/UdpReadable.h deleted file mode 100644 index 3836825..0000000 --- a/UdpReadable.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __UDPREDABLE_H__ -#define __UDPREDABLE_H__ - -#include -#include - -#include "Udp.h" - -class UdpReadable { - protected: - Udp _udp; - private: - struct event _evt; - static void __helper(int fd, short what, void *arg); - public: - int begin(const Udp &udp); - void end(); - virtual void isReadable(Udp &) = 0; - virtual ~UdpReadable() {end();} -}; - -#endif - diff --git a/Wan.cpp b/Wan.cpp deleted file mode 100644 index b0b24e8..0000000 --- a/Wan.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include "UdpEvent.h" -#include "Wan.h" -#include "Lan.h" -#include "Log.h" - -int Wan::begin(const char *group_addr, int port, const char *wlan_if, int stport) -{ - Udp udp; - - Log.printf("Wan group: %s, port: %d, wan: %s\n", group_addr, port, wlan_if); - if (udp.openMulticast(group_addr, port, wlan_if) < 0) { - Log.printf("'%s[%d]: can't create multicast socket\n", __FILE__, __LINE__); - return -1; - } - - if (_stSock.openMulticast(group_addr, stport, wlan_if) < 0) { - Log.printf("'%s[%d]: can't create status multicast socket\n", __FILE__, __LINE__); - udp.close(); - return -2; - } - UdpReadable::begin(udp); - - _stSeq = 0; - memset(&_stBuf, 0, sizeof _stBuf); - _stBuf.id1 = 0xAC; - _stBuf.id2 = 0x93; - _stBuf.id3 = 0x27; - _stBuf.id4 = 0x21; - _stBuf.srcPosId = 0xB1; - _stBuf.srcSwId = 0xD8; - _stBuf.destSwId = 0xE8; - _stBuf.initPosId = 0xB1; - _stBuf.contentId = 0xF3; - _stBuf.id5 = 0x14; - - return 0; -} - -void Wan::isReadable(Udp &u) -{ - uint8_t data[1500] = {0}; - int len; - - if ((len = u.recv(data, sizeof data)) <= 0) - return; - -#if 0 - Log.printf("Wan recv: %d bytes\n", len); - for (int i = 0; i < len; ++i) { - Log.printf("%02x%c", data[i], ((i + 1) % 16) ? ' ' : '\n'); - } - Log.printf("\n"); -#endif - - if ((data[0] == 0xAA) && (data[1] == 0x55)) { - if ((len == 32) && (data[6] == 0x91)) { - struct WanAudioType *wat = (struct WanAudioType *)data; - _audioDown->onDownAudio(wat); - } - } - /*XXX: if alarming , call _alarm->onAlarm() */ - if ((data[0] == 0xAC) && (data[1] == 0x93)) { - if ((len == 64) && (data[13] == 0xF0)) { - } - } -} - -void Wan::onPTT(Lan *ln, struct MsgCmd *hdr, uint8_t posId, bool on) -{ - if (on) { - } else { - } - ln->onResponse(on ? Lan::RESP_PTT_ON : Lan::RESP_PTT_OFF, hdr, RESP_PTT_OK); -} - -void Wan::onComplete(uint8_t *buf, int len) -{ - _udp.send(buf, len); -} - -void Wan::onStatus(uint8_t id, uint8_t status) -{ - int len = 0; - uint8_t *sbuf; - - _stBuf.destId = status ? id : 0; - /* - * 0: don't start - * 1: playing - * 2: idle - */ - _stBuf.status = status ? 0x01 : 0x02; - _stBuf.time = htonl(time(NULL)); - _stBuf.seq = htonl(++_stSeq); - uint32_t cs = 0; - len = sizeof _stBuf - 2; - sbuf = (uint8_t *)&_stBuf; - for (int x = 0; x < len; ++x) { - cs += sbuf[x]; - } - _stBuf.checkNum = cs & 0xff; - - len = _stSock.send(&_stBuf, sizeof _stBuf); - if (len < 0) { - Log.printf("%s:%d errno (%d) %s\n", __FILE__, __LINE__, errno, strerror(errno)); - } -// Log.printf("status sending %d bytes\n", len); -} - diff --git a/char_conv.c b/char_conv.c new file mode 100644 index 0000000..4d43161 --- /dev/null +++ b/char_conv.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include "runtime.h" +#include "udp_readable.h" +#include "char_conv.h" +#include "log.h" +#include "crc.h" + +struct alarm_handler { + struct wan_alarm_handler base; + char_conv_t *thiz; +}; + +struct char_conv { + struct udp_readable base; + struct alarm_handler alarm; + iconv_t cd; +}; + +#define LOIFADDR "127.0.0.1" + +struct wan_alarm_handler *char_conv_get_alarm_handler(char_conv_t *cv) +{ + return &cv->alarm.base; +} + +static void __is_readable(udp_readable_t *ur) +{ + uint8_t buf[1560] = {0}; + int len; + char_conv_t *cv; + + cv = (char_conv_t *)ur; + log_printf("char readable\n"); + if ((len = ur->udp->recv(ur->udp, buf, sizeof buf)) <= 0) + return; + log_printf("char conv recv: %d bytes\n", len); + /* XXX : packetizing ... */ +// Runtime.getLan().send(buf, len); +} + +static void __on_alarm(struct wan_alarm_handler *self, struct WanAlarmType *wat) +{ + uint8_t buf[1500] = {0}; + int idx = 0; + size_t len; + unsigned int cs; + struct alarm_handler *ah = (struct alarm_handler *)self; + char_conv_t *cv = ah->thiz; + + buf[idx++] = 0x68; + buf[idx++] = 0x00; + buf[idx++] = 0x00; + buf[idx++] = 0x80; + + for (len = 0; len < sizeof wat->msg; ++len) { + if (wat->msg[len] == 0) { + break; + } + } + + buf[idx++] = len & 0xff; + buf[idx++] = (len >> 8) & 0xff; + memcpy(buf + idx, wat->msg, len); + + idx += len; + + cs = crc(wat->msg, len); + + buf[idx++] = cs & 0xff; + buf[idx++] = (cs >> 8) & 0xff; + buf[idx++] = (cs >> 16) & 0xff; + buf[idx++] = (cs >> 24) & 0xff; + + do { + udp_t *_udp = cv->base.udp; + int n = _udp->send(_udp, buf, idx); + log_printf("conv sending: %d bytes\n", n); + } while (0); +} + +char_conv_t *char_conv_new(int to_port, int from_port) +{ + udp_t *u; + char_conv_t *cv; + + if ((u = udp_open()) == NULL) { + log_printf("'%s[%d]: can't create socket\n", __FILE__, __LINE__); + return NULL; + } + + if (u->bind(u, LOIFADDR, from_port) < 0) { + log_printf("'%s[%d]: can't bind [%s:%d] socket (%d: %s)\n", __FILE__, __LINE__, LOIFADDR, from_port, errno, strerror(errno)); + u->close(u); + return NULL; + } + if (u->connect(u, LOIFADDR, to_port) < 0) { + log_printf("'%s[%d]: can't connect [%s:%d] socket\n", __FILE__, __LINE__, LOIFADDR, to_port); + u->close(u); + return NULL; + } + + cv = (char_conv_t *)udp_readable_open(sizeof *cv, u); + cv->base.is_readable = __is_readable; + + cv->cd = iconv_open("GB2312", "UTF-8"); + if (cv->cd == (iconv_t)-1) { + log_printf("can't crate iconv conventer\n"); + udp_readable_close(&cv->base); + return NULL; + } + cv->alarm.base.on_alarm = __on_alarm; + cv->alarm.thiz = cv; + + return cv; +} + +void char_conv_free(char_conv_t *cv) +{ + iconv_close(cv->cd); + udp_readable_close(&cv->base); +} + diff --git a/char_conv.h b/char_conv.h new file mode 100644 index 0000000..d5f3d16 --- /dev/null +++ b/char_conv.h @@ -0,0 +1,11 @@ +#ifndef __CHAR_CONV_H__ +#define __CHAR_CONV_H__ + +#include "wan.h" +typedef struct char_conv char_conv_t; + +char_conv_t *char_conv_new(int to_port, int from_port); +struct wan_alarm_handler *char_conv_get_alarm_handler(char_conv_t *cv); +void char_conv_free(char_conv_t *cv); +#endif + diff --git a/codec.c b/codec.c new file mode 100644 index 0000000..ca130d2 --- /dev/null +++ b/codec.c @@ -0,0 +1,237 @@ +#include +#include +#include +#include +#include +#include "codec.h" +#include "log.h" +#include "lan.h" +#include "wan.h" +#include "udp_readable.h" +#include "IdMapper.h" + +struct uplink_audio_handler { + struct lan_audio_handler base; + codec_t *thiz; +}; + +struct downlink_audio_handler { + struct wan_audio_handler base; + codec_t *thiz; +}; + +struct udp_wrapper { + struct udp_readable base; + codec_t *thiz; +}; + +struct codec { + struct uplink_audio_handler _audio_up; + struct downlink_audio_handler _audio_down; + struct udp_wrapper *_uplink; + struct udp_wrapper *_downlink; + + struct codec_complete *_up_complete; + struct codec_complete *_down_complete; + + uint8_t _audioEncType; + struct AudioEncType _encBuf; + uint32_t _encSeq; + struct AudioDecInType _decBuf; + uint32_t _decSeq; +}; + +struct lan_audio_handler *codec_get_uplink_handler(codec_t *cc) +{ + return &cc->_audio_up.base; +} + +struct wan_audio_handler *codec_get_downlink_handler(codec_t *cc) +{ + return &cc->_audio_down.base; +} + +void codec_set_enc_type(codec_t *cc, int type) +{ + cc->_audioEncType = type; +} + +void codec_set_up_complete(codec_t *cc, struct codec_complete *ccp) +{ + cc->_up_complete = ccp; +} + +void codec_set_down_complete(codec_t *cc, struct codec_complete *ccp) +{ + cc->_down_complete = ccp; +} + +static uint8_t getcs(uint8_t *buf, int len) +{ + uint32_t sum = 0; + + for (int i = 0; i < len; ++i) { + sum += buf[i]; + } + + return (sum & 0xff); +} + +static void __on_up_audio( struct lan_audio_handler *lh, + struct MsgAudio *audio) +{ + struct uplink_audio_handler *uh = (struct uplink_audio_handler *)lh; + codec_t *cc = uh->thiz; + struct udp_wrapper *uw = cc->_uplink; + udp_t *u = uw->base.udp; + + memset(&cc->_encBuf, 0, sizeof cc->_encBuf); + + cc->_encBuf.id1 = 0xAC; + cc->_encBuf.id2 = 0x93; + cc->_encBuf.id3 = 0x27; + cc->_encBuf.id4 = 0x21; + cc->_encBuf.swId = 0xB1; + cc->_encBuf.fromId = 0xD8; + cc->_encBuf.toId = 0xFF; + cc->_encBuf.toSwId = 0xE2; + cc->_encBuf.origPosId = getMappedWanId(audio->sender); + cc->_encBuf.encType = cc->_audioEncType; + cc->_encBuf.contentId = 0xED; + cc->_encBuf.flyType = 0; + cc->_encBuf.flyId = 0; + + /* XXX: here need to convert */ + size_t len = audio->payloadLen; + if (len > sizeof cc->_encBuf.payload) + len = sizeof cc->_encBuf.payload; + memcpy(cc->_encBuf.payload, audio->payload, len); + + cc->_encBuf.timeStamp = htonl(time(NULL)); + cc->_encBuf.seqNum = htonl(++cc->_encSeq); + cc->_encBuf.checkNum = getcs((uint8_t *)&cc->_encBuf, sizeof cc->_encBuf - 2); + cc->_encBuf.id5 = 0x14; + + u->send(u, &cc->_encBuf, sizeof cc->_encBuf); +} + +static void __on_down_audio(struct wan_audio_handler *wh, struct WanAudioType *wat) +{ + struct downlink_audio_handler *dh = (struct downlink_audio_handler *)wh; + codec_t *cc = dh->thiz; + struct udp_wrapper *uw = cc->_downlink; + udp_t *u = uw->base.udp; + + memset(&cc->_decBuf, 0, sizeof cc->_decBuf); + + cc->_decBuf.id1 = 0xAC; + cc->_decBuf.id2 = 0x93; + cc->_decBuf.id3 = 0x27; + cc->_decBuf.id4 = 0x21; + cc->_decBuf.swId = 0xB1; + cc->_decBuf.origSwId = 0xD8; + cc->_decBuf.toId = 0xFF; + cc->_decBuf.toSwId = 0xE2; + cc->_decBuf.origPosId = 0xB1; + cc->_decBuf.encType = cc->_audioEncType; + cc->_decBuf.contentId = 0xED; + cc->_decBuf.flyType = wat->apType; + cc->_decBuf.flyId = wat->apId; + + memcpy(cc->_decBuf.payload, wat->mgrAudio, 6); + memcpy(cc->_decBuf.auxPayload, wat->auxAudio, 6); + cc->_decBuf.timeStamp = htonl(time(NULL)); + cc->_decBuf.seqNum = htonl(++cc->_decSeq); + cc->_decBuf.checkNum = getcs((uint8_t *)&cc->_decBuf, sizeof cc->_decBuf - 2); + cc->_decBuf.id5 = 0x14; + u->send(u, (uint8_t *)&cc->_decBuf, sizeof cc->_decBuf); +} + +static udp_t *__make_link(const char *bridge_ip, int bridge_port, const char *local_ip, int local_port) +{ + udp_t *_u; + if ((_u = udp_open()) == NULL) { + log_printf("'%s[%d]: can't create socket\n", __FILE__, __LINE__); + return NULL; + } + if (_u->bind(_u, local_ip, local_port) < 0) { + log_printf("'%s[%d]: can't bind [%s:%d] socket (%d: %s)\n", __FILE__, __LINE__, local_ip, local_port, errno, strerror(errno)); + _u->close(_u); + return NULL; + } + if (_u->connect(_u, bridge_ip, bridge_port) < 0) { + log_printf("'%s[%d]: can't connect [%s:%d] socket\n", __FILE__, __LINE__, local_ip, local_port); + _u->close(_u); + return NULL; + } + return _u; +} + +static void __up_readable(udp_readable_t *ur) +{ + int n; + uint8_t buf[1500] = {0}; + struct udp_wrapper *uw = (struct udp_wrapper *)ur; + codec_t *cc = uw->thiz; + udp_t *u = ur->udp; + struct codec_complete *ccp = cc->_up_complete; + + /* send to uplink */ + if ((n = u->recv(u, buf, sizeof buf)) > 0) { + ccp->on_complete(ccp, buf, n); + } +} + +static void __down_readable(udp_readable_t *ur) +{ + int n; + uint8_t buf[1500] = {0}; + struct udp_wrapper *uw = (struct udp_wrapper *)ur; + codec_t *cc = uw->thiz; + udp_t *u = ur->udp; + struct codec_complete *ccp = cc->_down_complete; + + /* send to uplink */ + if ((n = u->recv(u, buf, sizeof buf)) > 0) { + ccp->on_complete(ccp, buf, n); + } +} + +codec_t *codec_new(const char *bridge_ip, int bridge_port, const char *local_ip, int down_port, int up_port) +{ + codec_t *cc; + udp_t *d, *u; + + if ((d = __make_link(bridge_ip, bridge_port, local_ip, down_port)) == NULL) { + return NULL; + } + + if (( u = __make_link( bridge_ip, bridge_port, local_ip, up_port)) == NULL) { + d->close(d); + return NULL; + } + cc = calloc(1, sizeof *cc); + cc->_downlink = (struct udp_wrapper *)udp_readable_open(sizeof *cc->_downlink, d); + cc->_downlink->base.is_readable = __down_readable; + cc->_downlink->thiz = cc; + cc->_uplink = (struct udp_wrapper *)udp_readable_open(sizeof *cc->_uplink, u); + cc->_uplink->base.is_readable = __up_readable; + cc->_uplink->thiz = cc; + cc->_audio_up.thiz = cc; + cc->_audio_up.base.on_audio = __on_up_audio; + cc->_audio_down.thiz = cc; + cc->_audio_down.base.on_audio = __on_down_audio; + + return cc; +} + +void codec_free(codec_t *cc) +{ + struct udp_wrapper *uw; + uw = cc->_downlink; + udp_readable_close(&uw->base); + uw = cc->_uplink; + udp_readable_close(&uw->base); + free(cc); +} + diff --git a/codec.h b/codec.h new file mode 100644 index 0000000..b0ff5aa --- /dev/null +++ b/codec.h @@ -0,0 +1,77 @@ +#ifndef __AUDIO_CODEC_H__ +#define __AUDIO_CODEC_H__ + +#include +#include "lan.h" +#include "wan.h" + +#define AUDIO_ENC_ALL 0x00 +#define AUDIO_ENC_10 0x01 +#define AUDIO_ENC_712 0x02 + +#define AUDIO_ENC_PKT_LEN (666) +#define AUDIO_DEC_PKT_LEN (64) + +struct AudioEncType { + uint8_t id1; + uint8_t id2; + uint8_t id3; + uint8_t id4; + uint16_t resv0; + uint8_t swId; + uint8_t fromId; + uint8_t toId; + uint8_t toSwId; + uint8_t origPosId; + uint8_t resv1; + uint8_t encType; + uint8_t contentId; + uint8_t flyType; + uint8_t flyId; + uint8_t payload[640]; + uint32_t timeStamp; + uint32_t seqNum; + uint8_t checkNum; + uint8_t id5; +} __attribute__((packed)); + +struct AudioDecInType { + uint8_t id1; + uint8_t id2; + uint8_t id3; + uint8_t id4; + uint16_t resv0; + uint8_t swId; + uint8_t origSwId; + uint8_t toId; + uint8_t toSwId; + uint8_t origPosId; + uint8_t resv1; + uint8_t encType; + uint8_t contentId; + uint8_t flyType; + uint8_t flyId; + uint8_t payload[6]; + uint8_t auxPayload[6]; + uint8_t resv2[26]; + uint32_t timeStamp; + uint32_t seqNum; + uint8_t checkNum; + uint8_t id5; +} __attribute((packed)); + +struct codec_complete { + void (*on_complete)(struct codec_complete *, uint8_t *buf, int len); +}; + +typedef struct codec codec_t; +codec_t *codec_new(const char *bridge_ip, int bridge_port, const char *local_ip, int down_port, int up_port); +void codec_set_up_complete(codec_t *cc, struct codec_complete *ccp); +void codec_set_enc_type(codec_t *cc, int type); +void codec_set_down_complete(codec_t *cc, struct codec_complete *ccp); +struct lan_audio_handler *codec_get_uplink_handler(codec_t *cc); +struct wan_audio_handler *codec_get_downlink_handler(codec_t *cc); +void codec_free(codec_t *cc); + +#endif + diff --git a/CRC32.cpp b/crc.c similarity index 51% rename from CRC32.cpp rename to crc.c index 6efbdf3..110cc18 100644 --- a/CRC32.cpp +++ b/crc.c @@ -1,9 +1,10 @@ -#include "CRC32.h" +#include "crc.h" +static unsigned int crc_table[256]; /* * 初始化crc表,生成32位大小的crc表 * 也可以直接定义出crc表,直接查表, * */ -void Crc32::init(void) +void crc_begin(void) { unsigned int c; unsigned int i, j; @@ -20,24 +21,15 @@ void Crc32::init(void) } } -uint32_t Crc32::doCrc(uint32_t crc,unsigned char *buffer, unsigned int size) +unsigned int crc(void *_buffer, int size) { - unsigned int i; + int i; + unsigned int _crc = 0; + unsigned char *buffer = _buffer; + for (i = 0; i < size; i++) { - crc = crc_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8); + _crc = crc_table[(_crc ^ buffer[i]) & 0xff] ^ (_crc >> 8); } - return crc ; -} - -Crc32::Crc32() -{ - init(); -} - -uint32_t Crc32::crc(uint8_t *buffer, int len) -{ - uint32_t r = 0; - r = doCrc(r, buffer, len); - return r; + return _crc ; } diff --git a/crc.h b/crc.h new file mode 100644 index 0000000..2a83bb2 --- /dev/null +++ b/crc.h @@ -0,0 +1,7 @@ +#ifndef __CRC_H__ +#define __CRC_H__ + +void crc_begin(void); +unsigned int crc(void *buf, int len); +#endif + diff --git a/lan.c b/lan.c new file mode 100644 index 0000000..0180c29 --- /dev/null +++ b/lan.c @@ -0,0 +1,239 @@ +#include +#include +#include +#include +#include "IdMapper.h" +#include "udp_readable.h" +#include "log.h" +#include "lan.h" +#include "codec.h" + +#define LAN_PKT_MIN_LEN (16) +#define LAN_PKT_MAX_LEN (256) + +struct decode_handler { + struct codec_complete base; + lan_t *thiz; +}; + +struct lan { + struct udp_readable base; + uint32_t seqnum; + struct decode_handler dec; + struct lanmsg_handler *_provider; + struct lan_audio_handler *_uplink; +}; + +struct codec_complete *lan_get_decode_handler(lan_t *ln) +{ + return &ln->dec.base; +} + +void lan_set_msghandler(lan_t *ln, struct lanmsg_handler *h) +{ + ln->_provider = h; +} + +void lan_set_uplink_handler(lan_t *ln, struct lan_audio_handler *h) +{ + ln->_uplink = h; +} + +static void __on_downlink(struct codec_complete *cc, uint8_t *buf, int len) +{ + struct AudioEncType *aet; + struct MsgAudio *ma; + uint8_t msg[MSG_AUDIO_LEN] = {0}; + struct decode_handler *dh = (struct decode_handler *)cc; + udp_t *u = dh->thiz->base.udp; + + if (len < (int)(sizeof *aet)) { + log_printf("Audio too short.\n"); + return; + } + + ma = (struct MsgAudio *)(msg); + aet = (struct AudioEncType *)(buf); + ma->type = MSG_TYPE_AUDIO; + ma->recver = 0x19; + ma->sender = 0x07; + ma->swid = 0xB1; + ma->seqNum = htonl(++dh->thiz->seqnum); + ma->payloadLen = 160; + + /*XXX: transcode aet->payload */ + memcpy(ma->payload, aet->payload, ma->payloadLen); + + u->send(u, msg, sizeof msg); +} +static void __do_audio(lan_t *ln, uint8_t *buf, int len) +{ + struct MsgAudio *laph; + + if (len < (int)(sizeof *laph)) + return; + + laph = (struct MsgAudio *)(buf); + laph->payloadLen = ntohl(laph->payloadLen); + if (len < (int)(sizeof *laph + laph->payloadLen)) { + log_printf("audio length too small, total: %d, payload: %d\n", len, laph->payloadLen); + return; + } + + log_printf("recver< %d >: %x, sender: %x, mode: %d, recvChannel: %d, sendChannel: %d\n", + laph->payloadLen, laph->recver, laph->sender, laph->mode, laph->recvChannel, laph->sendChannel); + ln->_uplink->on_audio(ln->_uplink, laph); +} + +static void __do_cmd(lan_t *ln, udp_t *u, uint8_t *buf, int len) +{ + struct MsgCmd hdr, *sdp; + struct MsgTermStatus *mts; + uint8_t out; + uint16_t cmd; + + sdp = (struct MsgCmd *)(buf); + hdr = *sdp; + cmd = ntohs(hdr.msgCmd); + log_printf("Lan cmd [%02x]\n", cmd); + switch (cmd) { + case MSG_CMD_HANDSHAKE: + hdr.sender = sdp->recver; + hdr.recver = sdp->sender; + hdr.msgCmd = htons(MSG_RES_HANDSHAKE); +#if 1 + do { + uint8_t *dp; + dp = (uint8_t *)&hdr; + for (int x= 0; x < 12; ++x) { + log_printf("%02x ", dp[x]); + } + log_printf("\n"); + } while (0); +#endif + u->send(u, &hdr, sizeof hdr); + len -= sizeof hdr; + buf += sizeof hdr; + /* 6 x 4 bytes: + * 0 1 2 3 + * id downlink ptt alarm + */ + while (len > (int)sizeof (*mts)) { + mts = (struct MsgTermStatus *)buf; + out = getMappedWanId(mts->termId); + if (out > 0) { + ln->_provider->on_status(ln->_provider, out, mts->isAlarm); + } + len -= sizeof (*mts); + buf += sizeof (*mts); + } + break; + case MSG_CMD_PTTON: + out = getMappedWanId(hdr.sender); + if (out > 0) { + ln->_provider->on_ptt(ln->_provider, ln, &hdr, out, true); + } + break; + case MSG_CMD_PTTOFF: + out = getMappedWanId(hdr.sender); + if (out > 0) { + ln->_provider->on_ptt(ln->_provider, ln, &hdr, out, false); + } + break; + } +} + +static void __is_readable(udp_readable_t *ur) +{ + uint8_t buf[LAN_PKT_MAX_LEN] = {0}; + int len; + udp_t *_u = ur->udp; + + log_printf("lan reading\n"); + if ((len = _u->recv(_u, buf, sizeof buf)) < LAN_PKT_MIN_LEN) { + return; + } +#if 1 + do { + log_printf("Lan: %d bytes\n", len); + for (int x = 0; x < len; ++x) { + log_printf("%02x%c", buf[x], ((x + 1) % 16) ? ' ' : '\n'); + } + log_printf("\n"); + } while (0); +#endif + switch (buf[0]) { + case MSG_TYPE_CMD: + __do_cmd((lan_t *)(ur), _u, buf, len); + break; + case MSG_TYPE_AUDIO: + __do_audio((lan_t *)ur, buf, len); + break; + case MSG_TYPE_ALARM: + break; + } +} + +int lan_ptt_response(lan_t *ln, int resp_type, struct MsgCmd *hdr, int status) +{ + struct MsgCmd pkt; + udp_t *u = ln->base.udp; + + pkt = *hdr; + pkt.recver = hdr->sender; + pkt.sender = hdr->recver; + switch (resp_type) { + case RESP_PTT_ON: + if (status == RESP_PTT_OK) { + pkt.msgCmd = htons(MSG_RES_PTTON); + } else { + pkt.msgCmd = htons(MSG_REFUSE_PTTON); + } + break; + case RESP_PTT_OFF: + pkt.msgCmd = htons(MSG_RES_PTTOFF); + break; + } + u->send(u, &pkt, sizeof pkt); + + return 0; +} + +lan_t *lan_new(const char *dest_addr, int port, const char *local_if) +{ + udp_t *u; + lan_t *ln; + + if ((u = udp_open()) == NULL) { + log_printf("'%s[%d]: can't create Lan socket\n", __func__, __LINE__); + return NULL; + } + log_printf("local: %s, %s, %d\n", local_if, dest_addr, port); + if (u->bind(u, local_if, port) < 0) { + log_printf("'%s[%d]: can't bind Lan socket\n", __func__, __LINE__); + u->close(u); + return NULL; + } + + if (u->connect(u, dest_addr, port) < 0) { + log_printf("'%s[%d]: can't connect Lan socket\n", __func__, __LINE__); + u->close(u); + return NULL; + } + ln = (lan_t *)udp_readable_open(sizeof *ln, u); + if (ln == NULL) { + u->close(u); + return NULL; + } + ln->base.is_readable = __is_readable; + ln->seqnum = 0; + ln->dec.thiz = ln; + ln->dec.base.on_complete = __on_downlink; + return ln; +} + +void lan_free(lan_t *ln) +{ + udp_readable_close(&ln->base); +} + diff --git a/lan.h b/lan.h new file mode 100644 index 0000000..332f315 --- /dev/null +++ b/lan.h @@ -0,0 +1,117 @@ +#ifndef __LAN_H__ +#define __LAN_H__ +#include + +#define NOOFTERMS 6 + +#define MSG_TYPE_CMD 0x79 +#define MSG_TYPE_AUDIO 0x7A +#define MSG_TYPE_ALARM 0x7C + +#define MSG_CMD_HANDSHAKE 0x0003 +#define MSG_RES_HANDSHAKE 0x0002 +#define MSG_CMD_PTTON 0x0007 +#define MSG_RES_PTTON 0x0006 +#define MSG_REFUSE_PTTON 0x0005 +#define MSG_CMD_PTTOFF 0x000A +#define MSG_RES_PTTOFF 0x000B + +struct MsgCmd { + uint8_t type; + uint8_t recver; + uint8_t sender; + uint8_t swid; + uint16_t msgCmd; + uint8_t termId; + uint8_t channel; + uint32_t seqNum; +} __attribute__((packed)); + +struct MsgTermStatus { + uint8_t termId; + uint8_t isDowning; + uint8_t isPtt;; + uint8_t isAlarm; +} __attribute__((packed)); + +#define MSG_AUDIO_LEN (166) +struct MsgAudio { + uint8_t type; + uint8_t recver; + uint8_t sender; + uint8_t swid; + uint8_t reserv; + uint8_t mode; + uint8_t recvChannel; + uint8_t sendChannel; + uint32_t seqNum; + uint32_t payloadLen; + uint8_t payload[0]; +} __attribute__((packed)); + +struct MsgAlarm { + uint8_t type; + uint8_t recver; + uint8_t sender; + uint8_t swid; + uint16_t reserv; + uint8_t alarmPos; + uint8_t alarmTerm; + uint32_t seqNum; +} __attribute__((packed)); + +#define RESP_PTT_OK 0x01 +#define RESP_PTT_FAILED 0x02 + +typedef struct lan lan_t; + +struct lan_audio_handler { + void (*on_audio)(struct lan_audio_handler *, struct MsgAudio *); +}; + +struct lanmsg_handler { + void (*on_ptt)(struct lanmsg_handler *, lan_t *, struct MsgCmd *hdr, uint8_t posId, int on); + void (*on_status)(struct lanmsg_handler *, uint8_t id, uint8_t status); +}; + +enum {RESP_PTT_ON, RESP_PTT_OFF}; + +lan_t *lan_new(const char *dest_addr, int port, const char *local_if); +struct codec_complete *lan_get_decode_handler(lan_t *ln); +void lan_set_msghandler(lan_t *, struct lanmsg_handler *); +void lan_set_uplink_handler(lan_t *, struct lan_audio_handler *); +int lan_ptt_response(lan_t *ln, int resp_type, struct MsgCmd *hdr, int status); +void lan_free(lan_t *); + +#if 0 +class Lan : public AudioCompleteProvider , public UdpReadable { + private: + PTTProvider *_provider; + AudioUpProvider *_audioUp; + uint32_t _myseq; + void doCmd(uint8_t *buf, int len); + void doAudio(uint8_t *buf, int len); + public: + enum {RESP_PTT_ON, RESP_PTT_OFF}; + Lan() : _provider(0), _myseq(0) {} + + int begin(const char *group_addr, int port, const char *local_if); + + virtual void isReadable(Udp &udp); + + inline int send(const void *buf, int len) { + return _udp.send(buf, len); + } + + int onResponse(int resp_type, struct MsgCmd *hdr, int status); + + void setPTTProvider(PTTProvider *_p) {_provider = _p;} + void setAudioUpProvider(AudioUpProvider *_p) {_audioUp = _p;} + + /* down complete, multiast to lan */ + virtual void onComplete(uint8_t *buf, int len); +}; +#endif + +#endif + diff --git a/Log.cpp b/log.c similarity index 59% rename from Log.cpp rename to log.c index a866b1c..317b0b2 100644 --- a/Log.cpp +++ b/log.c @@ -1,9 +1,9 @@ #include #include -#include "Log.h" +#include "log.h" -int Log::printf(const char *fmt, ...) +int log_printf(const char *fmt, ...) { va_list ap; int n; @@ -14,13 +14,13 @@ int Log::printf(const char *fmt, ...) return (n); } -void Log::begin() +int log_begin() { + return 0; } -void Log::end() +int log_end() { + return 0; } -class Log Log; - diff --git a/log.h b/log.h new file mode 100644 index 0000000..ded5ebd --- /dev/null +++ b/log.h @@ -0,0 +1,7 @@ +#ifndef __NEWC_LOG_H__ +#define __NEWC_LOG_H__ +int log_begin(void); +int log_end(void); +int log_printf(const char *fmt,...); +#endif + diff --git a/main.c b/main.c new file mode 100644 index 0000000..8cdd25d --- /dev/null +++ b/main.c @@ -0,0 +1,10 @@ +#include "runtime.h" + +int main(int argc, char *argv[]) +{ + runtime_init(); + runtime_parse_args(argc, argv); + runtime_begin(); + return runtime_loop(); +} + diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 1fe2328..0000000 --- a/main.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "Runtime.h" -#include "Timer.h" - -int main(int argc, char *argv[]) -{ - Runtime.parseArgs(argc, argv); - Runtime.begin(); - if (0) { - Timer tm; - tm.begin(); - tm.active(1000); - } - return Runtime.loop(); -} - diff --git a/makefile b/makefile index 82b4529..d81b869 100644 --- a/makefile +++ b/makefile @@ -7,9 +7,9 @@ LIBDIR := $(TARGET_ROOT)/lib #DEBUG := -g -ggdb DEBUG := -O2 -s -CFLAGS += -D_GNU_SOURCE -I$(PWD) -I$(PWD)/class -I$(INCLUDE) -I$(INCLUDE)/luajit-2.0 -Wall -Wextra $(DEBUG) - -CXXFLAGS += $(CFLAGS) +CFLAGS += -std=gnu99 -D_GNU_SOURCE -fno-strict-aliasing \ + -I$(PWD) -I$(PWD)/class -I$(INCLUDE) -I$(INCLUDE)/luajit-2.0 -Wall -Wextra \ + $(DEBUG) LIBEVENT := -levent -levent_core -levent_extra -levent_pthreads LIBSNDFILE := @@ -18,13 +18,13 @@ LDFLAGS += -L$(TARGET_ROOT)/lib -Wl,--start-group,-Bstatic $(LIBEVENT) $(LIBSNDF #CLASS_OBJS := class/buffer.o class/event.o class/udp.o -OBJS := $(CLASS_OBJS) CRC32.o Udp.o UdpEvent.o UdpReadable.o Log.o Lan.o Wan.o AudioBridge.o CharConv.o Runtime.o Timer.o IdMapper.o main.o +OBJS := $(CLASS_OBJS) crc.o udp.o udp_readable.o log.o timer.o lan.o wan.o codec.o char_conv.o runtime.o IdMapper.o main.o comile: zkb @echo "compile done" zkb: $(OBJS) - $(CC) -o $@ $^ $(LDFLAGS) -lstdc++ + $(CC) -o $@ $^ $(LDFLAGS) clean: rm -rf $(OBJS) diff --git a/runtime.c b/runtime.c new file mode 100644 index 0000000..800ac79 --- /dev/null +++ b/runtime.c @@ -0,0 +1,174 @@ +#include +#include +#include +#include "runtime.h" +#include "log.h" +#include "udp.h" +#include "lan.h" +#include "wan.h" +#include "codec.h" +#include "crc.h" + +#define LAN_IF "eth0" +#define LAN_FROM "192.168.9.25" +#define LAN_PORT 5600 + +#define BGE_IP "192.168.9.19" +#define BGE_PORT 6419 +#define BGE_UP_PORT 6402 +#define BGE_DOWN_PORT 6400 + +/* + * Please disable rp_filter + * edit /etc/sysctl.conf + * + * net.ipv4.conf.default.rp_filter = 0 + * net.ipv4.conf.all.rp_filter = 0 + * + * add route for eth1 + * route add -net 192.168.31.0/24 dev eth1 + */ +#if 1 +#define WAN_IF "eth1" +#define WAN_GROUP "225.0.0.5" +#define WAN_GROUP_PORT 8300 +#define WAN_STATUS_PORT 8100 +#else +#define WAN_IF "eth0" +#define WAN_GROUP "224.0.0.24" +#define WAN_GROUP_PORT 8300 +#define WAN_STATUS_PORT 5100 +#endif + +struct runtime Runtime; + +void runtime_init() +{ + struct event_config *config; + + Runtime._lan_if = (char *)LAN_IF; + Runtime._lan_grp_addr = (char *)LAN_FROM; + Runtime._lan_grp_port = LAN_PORT; + + Runtime._bge_ip = (char *)BGE_IP; + Runtime._bge_port = BGE_PORT; + Runtime._up_port = BGE_UP_PORT; + Runtime._down_port = BGE_DOWN_PORT; + + Runtime._wan_if = (char *)WAN_IF; + Runtime._wan_grp_addr = (char *)WAN_GROUP; + Runtime._wan_grp_port = WAN_GROUP_PORT; + Runtime._wan_status_port = WAN_STATUS_PORT; + + config = event_config_new(); + event_config_avoid_method(config, "select"); + event_config_require_features(config, EV_FEATURE_ET); + Runtime.evbase = event_base_new_with_config(config); + event_config_free(config); + log_begin(); + crc_begin(); +} + +static void print_help() +{ + log_printf("usage: cmd [option], options as:\n\t" + "--lanif, -l: set lan ethx interface, eg: \"ethx\"\n\t" + "--landest, -g: set lan multicast address, eg: \"192.168.9.25\"\n\t" + "--lanport, -p: set lan multicast port, eg: 5600\n\t" + "--wanif, -w: set lan ethx interface, eg: \"ethx\"\n\t" + "--wangrp, -r: set lan multicast address, eg: \"255.0.0.5\"\n\t" + "--wanport, -t: set lan multicast port, eg: 5600\n\t" + "--help, -h: print this message.\n"); +} + +void runtime_parse_args(int argc, char *argv[]) +{ + int c; + static struct option options[] = { + {"lanif", required_argument, NULL, 'l'}, + {"landest", required_argument, NULL, 'g'}, + {"lanport", required_argument, NULL, 'p'}, + {"wanif", required_argument, NULL, 'w'}, + {"wangrp", required_argument, NULL, 'r'}, + {"wanport", required_argument, NULL, 't'}, + {"wanstport", required_argument, NULL, 'o'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0} + }; + + while ((c = getopt_long(argc, argv, "l:g:p:w:r:t:o:h", options, NULL)) != -1) { + switch (c) { + case 'l': + Runtime._lan_if = optarg; + break; + case 'g': + Runtime._lan_grp_addr = optarg; + break; + case 'p': + Runtime._lan_grp_port = atoi(optarg); + break; + case 'w': + Runtime._wan_if = optarg; + break; + case 'r': + Runtime._wan_grp_addr = optarg; + case 't': + Runtime._wan_grp_port = atoi(optarg); + break; + case 'o': + Runtime._wan_status_port = atoi(optarg); + break; + case 'h': + print_help(); + exit(0); + } + } +} + +void runtime_begin(void) +{ + char local_if[64] = {0}; + char wan_if[64] = {0}; + + getip(Runtime._lan_if, local_if, sizeof local_if); + if ((Runtime._lan = lan_new(Runtime._lan_grp_addr, Runtime._lan_grp_port, local_if)) == NULL) { + log_printf("lan initialize failed.\n"); + exit(-1); + } + + if ((Runtime._abge = codec_new(Runtime._bge_ip, Runtime._bge_port, local_if, Runtime._down_port, Runtime._up_port)) == NULL) { + log_printf("audio bridge initialize failed.\n"); + exit(-2); + } + + getip(Runtime._wan_if, wan_if, sizeof wan_if); + if ((Runtime._wan = wan_new(Runtime._wan_grp_addr, Runtime._wan_grp_port, wan_if, Runtime._wan_status_port)) == NULL) { + log_printf("wan initialize failed.\n"); + exit(-3); + } + + if ((Runtime._cv = char_conv_new(6801, 6802)) == NULL) { + log_printf("char convter initiazlie failed.\n"); + exit(-4); + } +#if 0 + static AlarmTimer at(&_conv); + at.begin(); + at.active(1000); +#endif + codec_set_down_complete(Runtime._abge, lan_get_decode_handler(Runtime._lan)); + codec_set_up_complete(Runtime._abge, wan_get_encode_handler(Runtime._wan)); + + lan_set_uplink_handler(Runtime._lan, codec_get_uplink_handler(Runtime._abge)); + wan_set_downlink_handler(Runtime._wan, codec_get_downlink_handler(Runtime._abge)); + + lan_set_msghandler(Runtime._lan, wan_get_msghandler(Runtime._wan)); + + wan_set_alarm_handler(Runtime._wan, char_conv_get_alarm_handler(Runtime._cv)); +} + +int runtime_loop() +{ + return event_base_dispatch(Runtime.evbase); +} + diff --git a/runtime.h b/runtime.h new file mode 100644 index 0000000..afd05f5 --- /dev/null +++ b/runtime.h @@ -0,0 +1,43 @@ +#ifndef __RUNTIME_H__ +#define __RUNTIME_H__ + +#include +#include "lan.h" +#include "wan.h" +#include "codec.h" +#include "char_conv.h" + +struct runtime { + struct event_base *evbase; + /* lan config */ + lan_t *_lan; + char *_lan_if; + char *_lan_grp_addr; + int _lan_grp_port; + + /* audio bridge */ + codec_t * _abge; + char *_bge_ip; + int _bge_port; + int _up_port; + int _down_port; + + /* Wan */ + wan_t *_wan; + char *_wan_if; + char *_wan_grp_addr; + int _wan_grp_port; + int _wan_status_port; + + /* char conv */ + char_conv_t *_cv; +}; + +extern struct runtime Runtime; +void runtime_parse_args(int argc, char *argv[]); +void runtime_init(void); +void runtime_begin(void); +int runtime_loop(void); + +#endif + diff --git a/timer.c b/timer.c new file mode 100644 index 0000000..3a301b0 --- /dev/null +++ b/timer.c @@ -0,0 +1,45 @@ +#include +#include "timer.h" +#include "log.h" +#include "runtime.h" + +static void __helper(int fd, short what, void *arg) +{ + struct timer *t = arg; + (void)fd; + (void)what; + t->on_timer(t); +} + +struct timer *timer_new(size_t alloc) +{ + struct timer *t; + + if (alloc < sizeof *t) + return NULL; + + t = calloc(1, alloc); + event_assign(&t->_evt, Runtime.evbase, -1, EV_TIMEOUT | EV_PERSIST, __helper, t); + return t; +} + +void timer_active(struct timer * t, int ms) +{ + struct timeval tv; + + tv.tv_sec = ms / 1000; + tv.tv_usec = ms % 1000; + + event_add(&t->_evt, &tv); +} + +void timer_deactive(struct timer *t) +{ + event_del(&t->_evt); +} + +void timer_free(struct timer *t) +{ + free(t); +} + diff --git a/timer.h b/timer.h new file mode 100644 index 0000000..05e4ec1 --- /dev/null +++ b/timer.h @@ -0,0 +1,17 @@ +#ifndef __ETIMER_H__ +#define __ETIMER_H__ + +#include +#include +struct timer { + struct event _evt; + void (*on_timer)(struct timer *); +}; + +struct timer *timer_new(size_t alloc); +void timer_active(struct timer *, int ms); +void timer_deactive(struct timer *); +void timer_free(struct timer *); + +#endif + diff --git a/Udp.cpp b/udp.c similarity index 50% rename from Udp.cpp rename to udp.c index 1b2969d..ac14abe 100644 --- a/Udp.cpp +++ b/udp.c @@ -1,21 +1,25 @@ #include +#include #include #include #include #include #include +#include +#include +#include +#include #include -#include "Udp.h" -#include "Log.h" +#include "udp.h" +#include "log.h" -Udp::Udp() -:sock(-1), isMcast(false) -{ - memset(&destAddr, 0, sizeof destAddr); -} +struct udp_multicast { + struct udp base; + struct sockaddr_in dest_addr; +}; -int Udp::bind(const char *addr, int p) +static int __bind(udp_t *s, const char *addr, int p) { struct sockaddr_in local_addr; @@ -24,69 +28,74 @@ int Udp::bind(const char *addr, int p) local_addr.sin_port = htons(p); local_addr.sin_addr.s_addr = addr ? inet_addr(addr) : INADDR_ANY; - return ::bind(sock, (struct sockaddr *)&local_addr, sizeof local_addr); + return bind(s->sock, (struct sockaddr *)&local_addr, sizeof local_addr); } -int Udp::open() +static int __close(udp_t *s) { - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock >= 0) { - evutil_make_socket_nonblocking(sock); - int reuse = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof reuse); - setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof reuse); - isMcast = false; - return 0; - } - return -1; + int n; + n = close(s->sock); + free(s); + return n; } -int Udp::close() +static int __connect(udp_t *s, const char *to, int p) { - int s; + struct sockaddr_in sin; + + memset(&sin, 0, sizeof sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(p); + sin.sin_addr.s_addr = inet_addr(to); - s = ::close(sock); - sock = -1; - return s; + return connect(s->sock, (struct sockaddr *)&sin, sizeof sin); } -int Udp::send(const void *buf, int len) +static int __send(udp_t *s, void *buf, int len) { - if (isMcast) { - return sendto(sock, buf, len, 0, (struct sockaddr *)&destAddr, - sizeof destAddr); - } else { - return write(sock, buf, len); - } + return write(s->sock, buf, len); } -int Udp::recv(void *buf, int len) +static int __recv(udp_t *s, void *buf, int len) { - return read(sock, buf, len); + return read(s->sock, buf, len); } -int Udp::connect(const char *to, int p) +static int __send2(udp_t *s, void *buf, int len) { - struct sockaddr_in sin; - - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(p); - sin.sin_addr.s_addr = inet_addr(to); + struct udp_multicast *_s = (struct udp_multicast *)(s); + return sendto(_s->base.sock, buf, len, 0, (struct sockaddr *)&_s->dest_addr, + sizeof _s->dest_addr); +} - return ::connect(sock, (struct sockaddr *)&sin, sizeof sin); +udp_t *udp_open() +{ + int s; + udp_t *u; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + return NULL; + u = calloc(1, sizeof *u); + u->sock = s; + u->bind = __bind; + u->connect = __connect; + u->send = __send; + u->recv = __recv; + u->close = __close; + return u; } -int Udp::openMulticast(const char *grp_addr, int port, const char *local) +udp_t * udp_open_mcast(const char *grp_addr, int port, const char *local) { struct sockaddr_in local_addr; struct ip_mreq group; struct in_addr ethx; - int sm = -1; + int sock; + struct udp_multicast *u; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { - goto done; + return NULL; } evutil_make_socket_nonblocking(sock); @@ -100,26 +109,26 @@ int Udp::openMulticast(const char *grp_addr, int port, const char *local) local_addr.sin_family = AF_INET; local_addr.sin_port = htons(port); local_addr.sin_addr.s_addr = INADDR_ANY; - if(::bind(sock, (struct sockaddr*)&local_addr, sizeof(local_addr))){ - Log.printf("%s[%d]: bind %d (%s)\n", __func__, __LINE__, errno, strerror(errno)); - ::close(sock); - goto done; + if(bind(sock, (struct sockaddr*)&local_addr, sizeof(local_addr))){ + log_printf("%s[%d]: bind %d (%s)\n", __func__, __LINE__, errno, strerror(errno)); + close(sock); + return NULL; } ethx.s_addr = inet_addr(local); if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, ðx, sizeof (ethx)) < 0) { - Log.printf("%s[%d]: setsockopt %d (%s)\n", __func__, __LINE__, errno, strerror(errno)); - ::close(sock); - goto done; + log_printf("%s[%d]: setsockopt %d (%s)\n", __func__, __LINE__, errno, strerror(errno)); + close(sock); + return NULL; } group.imr_multiaddr.s_addr = inet_addr(grp_addr); group.imr_interface.s_addr = inet_addr(local); if(setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0){ - Log.printf("%s[%d]: setsockopt %d (%s)\n", __func__, __LINE__, errno, strerror(errno)); - ::close(sock); - goto done; + log_printf("%s[%d]: setsockopt %d (%s)\n", __func__, __LINE__, errno, strerror(errno)); + close(sock); + return NULL; } /* don't lookback */ @@ -128,26 +137,29 @@ int Udp::openMulticast(const char *grp_addr, int port, const char *local) setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof loop); } while (0); - memset(&destAddr, 0, sizeof destAddr); + u = calloc(1, sizeof *u); - destAddr.sin_family = AF_INET; - destAddr.sin_port = htons(port); - destAddr.sin_addr.s_addr = inet_addr(grp_addr); - isMcast = true; + u->base.sock = sock; + u->base.bind = __bind; + u->base.connect = __connect; + u->base.send = __send2; + u->base.recv = __recv; + u->base.close = __close; - sm = 0; -done: - return sm; + u->dest_addr.sin_family = AF_INET; + u->dest_addr.sin_port = htons(port); + u->dest_addr.sin_addr.s_addr = inet_addr(grp_addr); + return &u->base; } -int Udp::getip(const char *ethx, char *addr, int len) +int getip(const char *ethx, char *addr, int len) { int ln, fd; struct ifreq ifr; int ret = 0; char *p; - fd = ::socket(AF_INET, SOCK_DGRAM, 0); + fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { return -1; } @@ -169,7 +181,7 @@ int Udp::getip(const char *ethx, char *addr, int len) ret = -1; } } - ::close(fd); + close(fd); return ret; } diff --git a/udp.h b/udp.h new file mode 100644 index 0000000..7f6d895 --- /dev/null +++ b/udp.h @@ -0,0 +1,18 @@ +#ifndef __UDP_NEWC_H__ +#define __UDP_NEWC_H__ +typedef struct udp udp_t; +struct udp { + int sock; + int (*bind)(udp_t *, const char *local_ip, int local_port); + int (*connect)(udp_t *, const char *remote_ip, int remote_port); + int (*send)(udp_t *, void *buf, int len); + int (*recv)(udp_t *, void *buf, int len); + int (*close)(udp_t *); +}; + +udp_t *udp_open(void); +udp_t *udp_open_mcast(const char *group, int port, const char *local_if); +int getip(const char *ethx, char *addr, int len); + +#endif + diff --git a/udp_readable.c b/udp_readable.c new file mode 100644 index 0000000..7f3b2be --- /dev/null +++ b/udp_readable.c @@ -0,0 +1,33 @@ +#include +#include "udp_readable.h" +#include "runtime.h" + +static void __helper(int fd , short what, void *arg) +{ + udp_readable_t *ur = arg; + (void)fd; + if (what & EV_READ) { + ur->is_readable(ur); + } +} + +udp_readable_t *udp_readable_open(size_t alloc_size, udp_t *u) +{ + udp_readable_t *ur; + + if (alloc_size < sizeof *ur) + return NULL; + ur = calloc(1, alloc_size); + ur->udp = u; + event_assign(&ur->evt, Runtime.evbase, u->sock, EV_READ | EV_PERSIST, __helper, ur); + event_add(&ur->evt, NULL); + return ur; +} + +void udp_readable_close(udp_readable_t *ur) +{ + event_del(&ur->evt); + ur->udp->close(ur->udp); + free(ur); +} + diff --git a/udp_readable.h b/udp_readable.h new file mode 100644 index 0000000..fab2bdd --- /dev/null +++ b/udp_readable.h @@ -0,0 +1,17 @@ +#ifndef __UDP_READABLE_H__ +#define __UDP_READABLE_H__ +#include +#include +#include "udp.h" + +typedef struct udp_readable udp_readable_t; +struct udp_readable { + struct event evt; + udp_t *udp; + void (*is_readable)(udp_readable_t *); +}; + +udp_readable_t *udp_readable_open(size_t alloc_size, udp_t *u); +void udp_readable_close(udp_readable_t *); +#endif + diff --git a/wan.c b/wan.c new file mode 100644 index 0000000..da543bd --- /dev/null +++ b/wan.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include "udp_readable.h" +#include "log.h" +#include "codec.h" +#include "wan.h" +#include "lan.h" + +struct encode_handler { + struct codec_complete base; + wan_t *thiz; +}; + +struct wanmsg_handler { + struct lanmsg_handler base; + wan_t *thiz; +}; + +struct wan { + struct udp_readable base; + struct encode_handler enc; + struct wanmsg_handler msghdr; + udp_t *stsock; + struct wan_audio_handler *_downlink; + struct wan_alarm_handler *_alarm; + struct WanStatusType _stBuf; + uint32_t _stSeq; +}; + +struct lanmsg_handler *wan_get_msghandler(wan_t *wn) +{ + return &wn->msghdr.base; +} + +void wan_set_downlink_handler(wan_t *wn, struct wan_audio_handler *h) +{ + wn->_downlink = h; +} + +void wan_set_alarm_handler(wan_t *wan, struct wan_alarm_handler *h) +{ + wan->_alarm = h; +} + +struct codec_complete *wan_get_encode_handler(wan_t *wn) +{ + return &wn->enc.base; +} + +static void __is_readable(udp_readable_t *ur) +{ + uint8_t data[1500] = {0}; + int len; + wan_t *wn = (wan_t *)ur; + udp_t *u = ur->udp; + + if ((len = u->recv(u, data, sizeof data)) <= 0) + return; + +#if 0 + Log.printf("Wan recv: %d bytes\n", len); + for (int i = 0; i < len; ++i) { + Log.printf("%02x%c", data[i], ((i + 1) % 16) ? ' ' : '\n'); + } + Log.printf("\n"); +#endif + + if ((data[0] == 0xAA) && (data[1] == 0x55)) { + if ((len == 32) && (data[6] == 0x91)) { + struct WanAudioType *wat = (struct WanAudioType *)data; + wn->_downlink->on_audio(wn->_downlink, wat); + } + } + /*XXX: if alarming , call _alarm->onAlarm() */ + if ((data[0] == 0xAC) && (data[1] == 0x93)) { + if ((len == 64) && (data[13] == 0xF0)) { + struct WanAlarmType *wmt = (struct WanAlarmType *)data; + wn->_alarm->on_alarm(wn->_alarm, wmt); + } + } +} + +static void __on_uplink(struct codec_complete *cc, uint8_t *buf, int len) +{ + struct encode_handler *eh = (struct encode_handler *)cc; + udp_t *u = eh->thiz->base.udp; + u->send(u, buf, len); +} + +static void __on_ptt(struct lanmsg_handler *lh, lan_t *ln, struct MsgCmd *hdr, uint8_t posId, int on) +{ + struct wanmsg_handler *wh = (struct wanmsg_handler *)lh; + wan_t *wn = wh->thiz; + + if (on) { + } else { + } + + lan_ptt_response(ln, on ? RESP_PTT_ON : RESP_PTT_OFF, hdr, RESP_PTT_OK); +} + +static void __on_status(struct lanmsg_handler *lh, uint8_t id, uint8_t status) +{ + struct wanmsg_handler *wh = (struct wanmsg_handler *)lh; + int len = 0; + uint8_t *sbuf; + wan_t *wn = wh->thiz; + + wn->_stBuf.destId = status ? id : 0; + /* + * 0: don't start + * 1: playing + * 2: idle + */ + wn->_stBuf.status = status ? 0x01 : 0x02; + wn->_stBuf.time = htonl(time(NULL)); + wn->_stBuf.seq = htonl(++wn->_stSeq); + uint32_t cs = 0; + len = sizeof wn->_stBuf - 2; + sbuf = (uint8_t *)&wn->_stBuf; + for (int x = 0; x < len; ++x) { + cs += sbuf[x]; + } + wn->_stBuf.checkNum = cs & 0xff; + + len = wn->stsock->send(wn->stsock, &wn->_stBuf, sizeof wn->_stBuf); + if (len < 0) { + log_printf("%s:%d errno (%d) %s\n", __FILE__, __LINE__, errno, strerror(errno)); + } +// Log.printf("status sending %d bytes\n", len); +} + +wan_t* wan_new(const char *group_addr, int port, const char *wlan_if, int stport) +{ + wan_t *wn; + udp_t *udp, *sts; + + log_printf("Wan group: %s, port: %d, wan: %s\n", group_addr, port, wlan_if); + if ((udp = udp_open_mcast(group_addr, port, wlan_if)) == NULL) { + log_printf("'%s[%d]: can't create multicast socket\n", __FILE__, __LINE__); + return NULL; + } + + if ((sts = udp_open_mcast(group_addr, stport, wlan_if)) == NULL) { + log_printf("'%s[%d]: can't create status multicast socket\n", __FILE__, __LINE__); + udp->close(udp); + return NULL; + } + wn = (wan_t *)udp_readable_open(sizeof *wn, udp); + wn->stsock = sts; + wn->_stSeq = 0; + wn->enc.thiz = wn; + wn->enc.base.on_complete = __on_uplink; + wn->base.is_readable = __is_readable; + wn->msghdr.thiz = wn; + wn->msghdr.base.on_ptt = __on_ptt; + wn->msghdr.base.on_status = __on_status; + + memset(&wn->_stBuf, 0, sizeof wn->_stBuf); + wn->_stBuf.id1 = 0xAC; + wn->_stBuf.id2 = 0x93; + wn->_stBuf.id3 = 0x27; + wn->_stBuf.id4 = 0x21; + wn->_stBuf.srcPosId = 0xB1; + wn->_stBuf.srcSwId = 0xD8; + wn->_stBuf.destSwId = 0xE8; + wn->_stBuf.initPosId = 0xB1; + wn->_stBuf.contentId = 0xF3; + wn->_stBuf.id5 = 0x14; + + return wn; +} + +void wan_free(wan_t *wn) +{ + wn->stsock->close(wn->stsock); + udp_readable_close(&wn->base); +} + diff --git a/Wan.h b/wan.h similarity index 55% rename from Wan.h rename to wan.h index c378650..0be0b09 100644 --- a/Wan.h +++ b/wan.h @@ -1,12 +1,7 @@ #ifndef __WAN_H__ #define __WAN_H__ -#include "PTTProvider.h" -#include "AudioProvider.h" -#include "AlarmProvider.h" -#include "UdpReadable.h" - -class Lan; +#include "lan.h" struct WanAudioType { uint8_t hdr0; @@ -67,32 +62,22 @@ struct WanStatusType { uint8_t id5; } __attribute__((packed)); -class Wan : public PTTProvider, public AudioCompleteProvider, public UdpReadable { -private: - AudioDownProvider *_audioDown; - AlarmProvider *_alarm; - Udp _stSock; - struct WanStatusType _stBuf; - uint32_t _stSeq; -public: - int begin(const char *group_addr, int port, const char *wlan_if, int stPort); - - void setAudioDownProvider(AudioDownProvider *_p) { _audioDown = _p;} - - void setAlarmProvider(AlarmProvider *_p) { _alarm = _p;} - - /* on recv */ - virtual void isReadable(Udp &); +struct wan_audio_handler { + void (*on_audio)(struct wan_audio_handler *self, struct WanAudioType *); +}; - /* PTT */ - virtual void onPTT(Lan *, struct MsgCmd *hdr, uint8_t posId, bool on); +struct wan_alarm_handler { + void (*on_alarm)(struct wan_alarm_handler *self, struct WanAlarmType *); +}; - /* status: 0 -> suspend , 1 -> alarming, 2 -> idle*/ - virtual void onStatus(uint8_t id, uint8_t status); +typedef struct wan wan_t; - /* uplink data */ - virtual void onComplete(uint8_t *buf, int len); -}; +wan_t* wan_new(const char *group_addr, int port, const char *wlan_if, int stport); +void wan_free(wan_t *wn); +void wan_set_alarm_handler(wan_t *wan, struct wan_alarm_handler *h); +void wan_set_downlink_handler(wan_t *, struct wan_audio_handler *); +struct codec_complete *wan_get_encode_handler(wan_t *wn); +struct lanmsg_handler *wan_get_msghandler(wan_t *wn); #endif