#include "misc.h"
#include "log-core.h"
+#define DEFAULT_CONNECT_TIMEOUT 20*1000 // ms
+#define DEFAULT_READWRITE_TIMEOUT 3*1000 // ms
+#define DEFAULT_IDLE_TIMEOUT 120*1000 // ms
+
const char *netscript=0;
int netTimeout=60*1000; // timeout for shutting down dialup-network
// -- cNetSocket ------------------------------------------------------------------
-cNetSocket::cNetSocket(int ConnectTimeout, int ReadWriteTimeout, int IdleTimeout, bool Udp)
+cNetSocket::cNetSocket(void)
{
- hostname=0; sd=-1; connected=netup=quietlog=false;
- udp=Udp; conTimeout=ConnectTimeout; rwTimeout=ReadWriteTimeout;
- idleTimeout=IdleTimeout*1000;
+ hostname=0; sd=-1; udp=connected=netup=quietlog=false;
+ conTimeout=DEFAULT_CONNECT_TIMEOUT; rwTimeout=DEFAULT_READWRITE_TIMEOUT;
+ idleTimeout=DEFAULT_IDLE_TIMEOUT;
}
cNetSocket::~cNetSocket()
return false;
}
-
bool cNetSocket::Bind(const char *Hostname, int Port)
{
nw.Block();
nw.Block();
cMutexLock lock(this);
if(sd>=0) { close(sd); sd=-1; }
- connected=false;
+ quietlog=connected=false;
if(netup) { nw.Down(this); netup=false; }
nw.Unblock();
}
}
}
-// len>0 : read available bytes, up to len
-// len<0 : block read len bytes or fail
+// len>0 : block read len bytes or fail
+// len<0 : read available bytes up to len
int cNetSocket::Read(unsigned char *data, int len, int timeout)
{
cMutexLock lock(this);
if(timeout<0) timeout=rwTimeout;
- bool fullread=false;
- if(len<0) { len=-len; fullread=true; }
+ bool blockmode=true;
+ if(len<0) { len=-len; blockmode=false; }
int cnt=0, r;
+ cTimeMs tim;
do {
- r=Select(true,timeout);
+ r=timeout;
+ if(blockmode) { r-=tim.Elapsed(); if(r<10) r=10; }
+ r=Select(true,r);
if(r>0) {
- r=LOOP_EINTR(read(sd,data,len));
+ r=LOOP_EINTR(read(sd,data+cnt,len-cnt));
if(r<0) PRINTF(L_GEN_ERROR,"socket: read failed: %s",strerror(errno));
else if(r>0) cnt+=r;
+ else {
+ PRINTF(L_GEN_ERROR,"socket: EOF on read");
+ errno=ECONNRESET;
+ }
}
- } while(r>0 && cnt<len && fullread);
+ } while(r>0 && cnt<len && blockmode);
Activity();
- if(r>0) {
+ if((!blockmode && cnt>0) || cnt>=len) {
HEXDUMP(L_CORE_NETDATA,data,cnt,"network read");
return cnt;
}
- return r;
+ return -1;
}
int cNetSocket::Write(const unsigned char *data, int len, int timeout)
cMutexLock lock(this);
if(timeout<0) timeout=rwTimeout;
int cnt=0, r;
+ cTimeMs tim;
do {
- r=Select(false,timeout);
+ r=timeout-tim.Elapsed(); if(r<10) r=10;
+ r=Select(false,r);
if(r>0) {
r=LOOP_EINTR(write(sd,data+cnt,len-cnt));
if(r<0) PRINTF(L_GEN_ERROR,"socket: write failed: %s",strerror(errno));
}
} while(r>0 && cnt<len);
Activity();
- if(r>0) {
+ if(cnt>=len) {
HEXDUMP(L_CORE_NETDATA,data,cnt,"network write");
return cnt;
}
- return r;
+ return -1;
}
int cNetSocket::SendTo(const char *Host, int Port, const unsigned char *data, int len, int timeout)
int cnt=0, r=-1;
struct sockaddr_in saddr;
if(GetAddr(&saddr,Host,Port)) {
+ cTimeMs tim;
do {
- r=Select(false,timeout);
+ r=timeout-tim.Elapsed(); if(r<10) r=10;
+ r=Select(false,r);
if(r>0) {
- r=LOOP_EINTR(sendto(sd,data,len,0,(struct sockaddr *)&saddr,sizeof(saddr)));
+ r=LOOP_EINTR(sendto(sd,data+cnt,len-cnt,0,(struct sockaddr *)&saddr,sizeof(saddr)));
if(r<0) PRINTF(L_GEN_ERROR,"socket: sendto %d.%d.%d.%d:%d failed: %s",(saddr.sin_addr.s_addr>> 0)&0xff,(saddr.sin_addr.s_addr>> 8)&0xff,(saddr.sin_addr.s_addr>>16)&0xff,(saddr.sin_addr.s_addr>>24)&0xff,Port,strerror(errno));
else if(r>0) cnt+=r;
}
} while(r>0 && cnt<len);
}
Activity();
- if(r>0) {
+ if(cnt>=len) {
HEXDUMP(L_CORE_NETDATA,data,cnt,"network sendto %d.%d.%d.%d:%d",(saddr.sin_addr.s_addr>> 0)&0xff,(saddr.sin_addr.s_addr>> 8)&0xff,(saddr.sin_addr.s_addr>>16)&0xff,(saddr.sin_addr.s_addr>>24)&0xff,Port);
return cnt;
}
- return r;
+ return -1;
}
int cNetSocket::Select(bool forRead, int timeout)
fd_set fds;
FD_ZERO(&fds); FD_SET(sd,&fds);
struct timeval tv;
- if(timeout&MSTIMEOUT) { tv.tv_sec=0; tv.tv_usec=(timeout&~MSTIMEOUT)*1000; }
- else { tv.tv_sec=timeout; tv.tv_usec=0; }
+
+ if(timeout>0 && timeout<60)
+ PRINTF(L_GEN_DEBUG,"socket: internal: small timeout value %d",timeout);
+
+ tv.tv_sec=timeout/1000; tv.tv_usec=(timeout%1000)*1000;
int r=LOOP_EINTR(select(sd+1,forRead ? &fds:0,forRead ? 0:&fds,0,&tv));
if(r>0) return 1;
else if(r<0) {
return -1;
}
else {
- if(timeout>0 && !quietlog) PRINTF(L_CORE_NET,"socket: select timed out (%d %s)",timeout&~MSTIMEOUT,(timeout&MSTIMEOUT)?"ms":"secs");
+ if(timeout>0 && !quietlog) PRINTF(L_CORE_NET,"socket: select timed out (%d ms)",timeout);
+ errno=ETIMEDOUT;
return 0;
}
}
// ----------------------------------------------------------------
-#define DEFAULT_CONNECT_TIMEOUT 20
-#define DEFAULT_READWRITE_TIMEOUT 3
-#define DEFAULT_IDLE_TIMEOUT 120
-
-#define MSTIMEOUT 0x800000
-
extern const char *netscript;
extern int netTimeout;
bool GetAddr(struct sockaddr_in *saddr, const char *Hostname, int Port);
int GetSocket(bool Udp);
public:
- cNetSocket(int ConnectTimeout, int ReadWriteTimeout, int IdleTimeout, bool Udp=false);
+ cNetSocket(void);
~cNetSocket();
bool Connect(const char *Hostname, int Port, int timeout=-1);
bool Bind(const char *Hostname, int Port);
void Flush(void);
bool Connected(void) { return connected; }
void SetQuietLog(bool ql) { quietlog=ql; }
+ void SetConnectTimeout(int to) { conTimeout=to; }
+ void SetRWTimeout(int to) { rwTimeout=to; }
+ void SetIdleTimeout(int to) { idleTimeout=to; }
+ void SetUDP(bool u) { udp=u; }
};
#endif //___NETWORK_H
#include <string.h>
#include "cc.h"
-#include "network.h"
#include "parse.h"
// -- cCardClientAroureos ------------------------------------------------------
class cCardClientAroureos : public cCardClient, protected cIdSet {
private:
- cNetSocket so;
- //
bool ParseCardConfig(const char *config, int *num);
protected:
virtual bool Login(void);
cCardClientAroureos::cCardClientAroureos(const char *Name)
:cCardClient(Name)
-,so(DEFAULT_CONNECT_TIMEOUT,5,DEFAULT_IDLE_TIMEOUT)
-{}
+{
+ so.SetRWTimeout(5*1000);
+}
bool cCardClientAroureos::ParseCardConfig(const char *config, int *num)
{
unsigned char *buff=AUTOMEM(length+8);
memcpy(buff,"EMM",3);
memcpy(&buff[3],source,length);
- SendMsg(&so,buff,length+3);
+ SendMsg(buff,length+3);
msEMM.Cache(id,true,0);
}
return true;
memcpy(buff,"ECM",3);
memcpy(&buff[3],source,len);
- if(!SendMsg(&so,buff,96)) return false;
- int n=RecvMsg(&so,buff,sizeof(buff));
- if(n>0) {
+ if(!SendMsg(buff,96)) return false;
+ if(RecvMsg(buff,16)>0 && !CheckNull(buff,16)) {
memcpy(cw,buff,16);
- for(n=0; n<16; n++) if(cw[n]) break;
- if(n<16) return true;
+ return true;
}
}
return false;
#include <byteswap.h>
#include "cc.h"
-#include "network.h"
#include "crypto.h"
#include "misc.h"
#include "parse.h"
cCondVar sleepCond;
cTimeMs time;
protected:
- cNetSocket so;
bool emmProcessing;
char username[11], password[11];
+ int emmReqLen;
//
virtual bool Login(void);
bool ParseKeyConfig(const char *config, int *num);
bool ParseUserConfig(const char *config, int *num);
- virtual bool SendMsg(cNetSocket *so, const unsigned char *data, int len);
- virtual int RecvMsg(cNetSocket *so, unsigned char *data, int len, int to=-1);
+ virtual bool SendMsg(const unsigned char *data, int len);
+ virtual int RecvMsg(unsigned char *data, int len, int to=-1);
virtual void HandleEMMRequest(const unsigned char *buff, int len) {}
virtual bool CanHandleEMM(int SysId) { return false; }
public:
cCardClientCommon::cCardClientCommon(const char *Name, bool ConReply, bool LogReply, bool DoAES, int MinMsgLen)
:cCardClient(Name)
-,so(DEFAULT_CONNECT_TIMEOUT,CCTIMEOUT/1000,DEFAULT_IDLE_TIMEOUT)
{
conReply=ConReply; logReply=LogReply; doAES=DoAES; minMsgLen=MinMsgLen;
emmProcessing=exclusive=false;
+ so.SetRWTimeout(CCTIMEOUT);
+ emmReqLen=-64;
}
bool cCardClientCommon::ParseUserConfig(const char *config, int *num)
return true;
}
-bool cCardClientCommon::SendMsg(cNetSocket *so, const unsigned char *data, int len)
+bool cCardClientCommon::SendMsg(const unsigned char *data, int len)
{
unsigned char *buff2=AUTOMEM(minMsgLen);
if(len<minMsgLen) {
unsigned char *buff=AUTOMEM(len+16);
const int l=Encrypt(data,len,buff);
if(l>0) { data=buff; len=l; }
- return cCardClient::SendMsg(so,data,len);
+ return cCardClient::SendMsg(data,len);
}
-int cCardClientCommon::RecvMsg(cNetSocket *so, unsigned char *data, int len, int to)
+int cCardClientCommon::RecvMsg(unsigned char *data, int len, int to)
{
- int n=cCardClient::RecvMsg(so,data,len,to);
+ int n=cCardClient::RecvMsg(data,len,to);
if(n>0) {
if(n&15) PRINTF(L_CC_CAMD,"AES crypted message length not a multiple of 16");
Decrypt(data,n);
unsigned char buff[128];
if(conReply) {
- if(RecvMsg(&so,buff,sizeof(buff))!=16) {
+ if(RecvMsg(buff,16)<0) {
PRINTF(L_CC_CAMD,"bad connect reply");
return false;
}
int vers_len=strlen(CCVERSION)+1;
memcpy(buff+1+user_len+pass_len+1,CCVERSION,vers_len);
PRINTF(L_CC_CAMD,"login user='%s' password=hidden version=%s",username,CCVERSION);
- if(!SendMsg(&so,buff,32)) return false;
+ if(!SendMsg(buff,32)) return false;
if(emmAllowed && logReply) {
PRINTF(L_CC_CAMD,"waiting for login reply ...");
- int r=RecvMsg(&so,buff,sizeof(buff));
+ int r=RecvMsg(buff,emmReqLen);
if(r>0) HandleEMMRequest(buff,r);
}
PRINTF(L_CC_LOGIN,"%s: login done",name);
buff[6]=((cCardIrdeto *)card)->hexBase;
memcpy(&buff[7],source,length);
//PRINTF(L_CC_CAMD,"%s: sending EMM for caid 0x%04X",name,caSys);
- SendMsg(&so,buff,length+7);
+ SendMsg(buff,length+7);
msEMM.Cache(id,true,0);
}
return true;
const int length=SCT_LEN(source);
unsigned char *buff=AUTOMEM(length+32);
int n;
- while((n=RecvMsg(&so,buff,16,0))>0) HandleEMMRequest(buff,n);
+ while((n=RecvMsg(buff,-16,0))>0) HandleEMMRequest(buff,n);
buff[0]=0x02;
buff[1]=(ecm->caId>>8);
buff[2]=(ecm->caId&0xFF);
memset(&buff[3],0,4);
memcpy(&buff[7],source,length);
- if(SendMsg(&so,buff,length+7)) {
+ if(SendMsg(buff,length+7)) {
exclusive=true;
time.Set(CCTIMEOUT);
do {
sleepCond.TimedWait(*this,50);
- while((n=RecvMsg(&so,buff,32,0))>0) {
+ while((n=RecvMsg(buff,-32,0))>0) {
if(n>=21 && buff[0]==2) {
if(!CheckNull(buff+5,16)) {
if(!res) {
// -- cCardClientCamd33 --------------------------------------------------------
+#define EMMREQLEN33 13
+
class cCardClientCamd33 : public cCardClientCommon {
private:
int CAID;
{
CAID=0;
memset(lastEmmReq,0,sizeof(lastEmmReq));
+ emmReqLen=EMMREQLEN33;
}
bool cCardClientCamd33::CanHandle(unsigned short SysId)
void cCardClientCamd33::HandleEMMRequest(const unsigned char *buff, int len)
{
- if(len>=13 && buff[0]==0 && !CheckNull(buff,len) && memcmp(buff,lastEmmReq,13)) {
+ if(len>=emmReqLen && buff[0]==0 && !CheckNull(buff,len) && memcmp(buff,lastEmmReq,emmReqLen)) {
emmProcessing=false;
int c=buff[1]*256+buff[2];
if(c!=CAID) CaidsChanged();
unsigned char buff[128];
memset(buff,0,sizeof(buff));
buff[0]=0x0A;
- if(!SendMsg(&so,buff,32)) return false;
- int n=RecvMsg(&so,buff,sizeof(buff));
+ if(!SendMsg(buff,32)) return false;
+ int n=RecvMsg(buff,-sizeof(buff));
if(n<0) return false;
for(int i=1; i<n && numCAIDs<MAX_CAIDS; i+=2) {
unsigned short caid=(buff[i+1]<<8)+buff[i];
cCondVar sleepCond;
cTimeMs time;
protected:
- cNetSocket so;
bool emmProcessing;
char username[33], password[33];
int numCaids, Caids[8];
cCardClientCamd35::cCardClientCamd35(const char *Name)
:cCardClient(Name)
-,so(DEFAULT_CONNECT_TIMEOUT,CCTIMEOUT/1000,DEFAULT_IDLE_TIMEOUT,true)
{
emmProcessing=exclusive=emmCmd06=false; pinid=0; numCaids=0; lastEmmReq=0;
memset(Dx,0,sizeof(Dx));
+ so.SetRWTimeout(CCTIMEOUT);
+ so.SetUDP(true);
}
bool cCardClientCamd35::ParseUserConfig(const char *config, int *num)
HEXDUMP(L_CC_CAMDEXTR,cb,datalen+UCSIZE(cb),"send:");
const int l=Encrypt((unsigned char *)cb+UCSIZE(cb),datalen,buff+UCSIZE(cb));
if(l<=0) return false;
- return cCardClient::SendMsg(&so,buff,l+UCSIZE(cb));
+ return cCardClient::SendMsg(buff,l+UCSIZE(cb));
}
int cCardClientCamd35::RecvBlock(struct CmdBlock *cb, int maxlen, int to)
{
- int n=cCardClient::RecvMsg(&so,(unsigned char *)cb,maxlen,to);
- if(n<=0) return n;
- if((unsigned int)n>=CBSIZE(cb)+UCSIZE(cb)) {
- if(cb->ucrc==ucrc) {
- Decrypt((unsigned char *)cb+UCSIZE(cb),n-UCSIZE(cb));
- if((unsigned int)n<cb->udp_header.len+CBSIZE(cb)+UCSIZE(cb))
- PRINTF(L_CC_CAMD35,"packet length doesn't match data length");
- else if(cb->udp_header.crc!=bswap_32(crc32_le(0,&cb->data[0],cb->udp_header.len)))
- PRINTF(L_CC_CAMD35,"data crc failed");
- else {
- HEXDUMP(L_CC_CAMDEXTR,cb,n,"recv:");
- return n;
- }
- }
- else PRINTF(L_CC_CAMD35,"wrong ucrc: got %08x, want %08x",cb->ucrc,ucrc);
+ unsigned char *m=(unsigned char *)cb;
+ if(cCardClient::RecvMsg(m,16+UCSIZE(cb),to)<0) {
+ PRINTF(L_CC_CAMD35,"short packet received");
+ return -1;
+ }
+ Decrypt(m+UCSIZE(cb),16);
+ int n=cb->udp_header.len+HDSIZE(cb);
+ if(n>maxlen) {
+ PRINTF(L_CC_CAMD35,"received buffer overflow");
+ return -1;
}
- else PRINTF(L_CC_CAMD35,"short packet received");
- return -1;
+ if(cCardClient::RecvMsg(m+16+UCSIZE(cb),n-(16+UCSIZE(cb)),200)<0) {
+ PRINTF(L_CC_CAMD35,"short packet received(2)");
+ return -1;
+ }
+ Decrypt(m+16+UCSIZE(cb),n-(16+UCSIZE(cb)));
+ if(cb->ucrc!=ucrc) {
+ PRINTF(L_CC_CAMD35,"wrong ucrc: got %08x, want %08x",cb->ucrc,ucrc);
+ return -1;
+ }
+ if(cb->udp_header.crc!=bswap_32(crc32_le(0,&cb->data[0],cb->udp_header.len))) {
+ PRINTF(L_CC_CAMD35,"data crc failed");
+ return -1;
+ }
+ HEXDUMP(L_CC_CAMDEXTR,cb,n,"recv:");
+ return n;
}
bool cCardClientCamd35::Init(const char *config)
#include "system.h"
#include "cc.h"
#include "sc.h"
-#include "network.h"
#include "misc.h"
#include "opts.h"
#include "log-core.h"
return false;
}
-bool cCardClient::SendMsg(cNetSocket *so, const unsigned char *data, int len)
+bool cCardClient::SendMsg(const unsigned char *data, int len)
{
- if(!so->Connected() && !Login()) return false;
- if(so->Write(data,len)<0) {
+ if(!so.Connected() && !Login()) return false;
+ if(so.Write(data,len)<0) {
PRINTF(L_CC_CORE,"send error. reconnecting...");;
- so->Disconnect();
+ so.Disconnect();
return false;
}
return true;
}
-int cCardClient::RecvMsg(cNetSocket *so, unsigned char *data, int len, int to)
+int cCardClient::RecvMsg(unsigned char *data, int len, int to)
{
- if(!so->Connected() && !Login()) return -1;
- int n=so->Read(data,len,to);
- if(n<0 || (n==0 && to!=0)) {
+ if(!so.Connected() && !Login()) return -1;
+ int n=so.Read(data,len,to);
+ if(n<0) {
PRINTF(L_CC_CORE,"recv error. reconnecting...");;
- so->Disconnect();
- return -1;
+ so.Disconnect();
}
return n;
}
#include <vdr/thread.h>
#include "system.h"
+#include "network.h"
#include "misc.h"
#include "log.h"
class cCardClient : public cStructItem, protected cMutex {
friend class cSystemCardClient;
protected:
+ cNetSocket so;
const char *name;
char hostname[64];
int port;
cMsgCache msECM, msEMM;
//
bool ParseStdConfig(const char *config, int *num=0);
- virtual bool SendMsg(cNetSocket *so, const unsigned char *data, int len);
- virtual int RecvMsg(cNetSocket *so, unsigned char *data, int len, int to=-1);
+ virtual bool SendMsg(const unsigned char *data, int len);
+ virtual int RecvMsg(unsigned char *data, int len, int to=-1);
virtual bool Login(void) { return false; }
bool Immediate(void);
void CaidsChanged(void);
#include <vdr/pat.h>\r
\r
#include "cc.h"\r
-#include "network.h"\r
\r
#define LIST_ONLY 0x03 /* CA application should clear the list when an 'ONLY' CAPMT object is received, and start working with the object */\r
\r
\r
class cCardClientCCcam : public cCardClient, private cThread {\r
private:\r
- cNetSocket so;\r
cCCcamCard card[4];\r
int pmtversion;\r
int failedcw;\r
cCardClientCCcam::cCardClientCCcam(const char *Name)\r
:cCardClient(Name)\r
,cThread("CCcam listener")\r
-,so(DEFAULT_CONNECT_TIMEOUT,2,3600,true)\r
{\r
pmtversion=0; socketpath=0;\r
+ so.SetRWTimeout(2*1000);\r
+ so.SetUDP(true);\r
}\r
\r
cCardClientCCcam::~cCardClientCCcam()\r
{\r
cMutexLock lock(this);\r
so.Disconnect();\r
- so.SetQuietLog(true);\r
if(!so.Bind("127.0.0.1",port)) return false;\r
+ so.SetQuietLog(true);\r
PRINTF(L_CC_CCCAM,"Bound to port %d, starting UDP listener",port);\r
Start();\r
return true;\r
{\r
unsigned char cw[18];\r
while(Running()) {\r
- int r=so.Read(cw,sizeof(cw));\r
- if(r==sizeof(cw)) {\r
+ if(so.Read(cw,sizeof(cw)>0)) {\r
LDUMP(L_CC_CCCAM,cw+2,16,"got: %02x%02x ",cw[0],cw[1]);\r
if(cw[1]==0x0f && cw[0]<4)\r
card[cw[0]].NewCw(cw+2);\r
}\r
- else if(r>0) PRINTF(L_CC_CCCAM,"unexpected read length r=%d",r);\r
}\r
}\r
#include <openssl/sha.h>
#include "cc.h"
-#include "network.h"
#include "helper.h"
#include "version.h"
private:
cCCcamCrypt encr, decr;
cShares shares;
- cNetSocket so;
unsigned char nodeid[8];
int shareid;
char username[21], password[64];
cCardClientCCcam2::cCardClientCCcam2(const char *Name)
:cCardClient(Name)
,cThread("CCcam2 listener")
-,so(DEFAULT_CONNECT_TIMEOUT,2,600)
{
shareid=0; newcw=login=false;
+ so.SetRWTimeout(10*1000);
}
cCardClientCCcam2::~cCardClientCCcam2()
unsigned char buffer[512];
int len;
- if((len=so.Read(buffer,sizeof(buffer),10))<=0) {
+ if((len=so.Read(buffer,16))<0) {
PRINTF(L_CC_CCCAM2,"no welcome from server");
Logout();
return false;
}
LDUMP(L_CC_CCCAM2DT,buffer,len,"welcome answer:");
- if(len!=16 || !cCCcamCrypt::CheckConnectChecksum(buffer,len)) {
+ if(!cCCcamCrypt::CheckConnectChecksum(buffer,len)) {
PRINTF(L_CC_CCCAM2,"bad welcome from server");
Logout();
return false;
LDUMP(L_CC_CCCAM2DT,buff2,20,"welcome response:");
encr.Encrypt(buff2,buffer,20);
- if(so.Write(buffer,20)!=20) {
+ if(so.Write(buffer,20)<0) {
PRINTF(L_CC_CCCAM2,"failed to send welcome response");
Logout();
return false;
strcpy((char *)buff2,username);
LDUMP(L_CC_CCCAM2DT,buff2,20,"send username:");
encr.Encrypt(buff2,buffer,20);
- if(so.Write(buffer,20)!=20) {
+ if(so.Write(buffer,20)<0) {
PRINTF(L_CC_CCCAM2,"failed to send username");
Logout();
return false;
encr.Encrypt((unsigned char *)password,buffer,strlen(password));
encr.Encrypt((unsigned char *)cccamstr,buffer,6);
- if(so.Write(buffer,6)!=6) {
+ if(so.Write(buffer,6)<0) {
PRINTF(L_CC_CCCAM2,"failed to send password hash");
Logout();
return false;
}
- if((len=so.Read(buffer,sizeof(buffer),6))<=0) {
+ if((len=so.Read(buffer,20))<0) {
PRINTF(L_CC_CCCAM2,"no login answer from server");
Logout();
return false;
decr.Decrypt(buffer,buffer,len);
LDUMP(L_CC_CCCAM2DT,buffer,len,"login answer:");
- if(len<20 || strcmp(cccamstr,(char *)buffer)!=0) {
+ if(strcmp(cccamstr,(char *)buffer)!=0) {
PRINTF(L_CC_CCCAM2,"login failed");
Logout();
return false;
memcpy(clt.nodeid,nodeid,8);
LDUMP(L_CC_CCCAM2DT,&clt,sizeof(clt),"send clientinfo:");
encr.Encrypt((unsigned char*)&clt,buffer,sizeof(clt));
- if(so.Write(buffer,sizeof(clt))!=sizeof(clt)) {
+ if(so.Write(buffer,sizeof(clt))<0) {
PRINTF(L_CC_CCCAM2,"failed to send clientinfo");
Logout();
return false;
PRINTF(L_CC_CCCAM2EX,"now try shareid %08x",shareid);
LDUMP(L_CC_CCCAM2DT,req,ecm_len,"send ecm:");
encr.Encrypt((unsigned char *)req,netbuff,ecm_len);
- if(so.Write(netbuff,ecm_len)!=ecm_len) {
+ if(so.Write(netbuff,ecm_len)<0) {
PRINTF(L_CC_CCCAM2,"failed so send ecm request");
Logout();
break;
int cnt=0;
while(Running() && so.Connected()) {
unsigned char recvbuff[1024];
- int len=so.Read(recvbuff+cnt,sizeof(recvbuff)-cnt,MSTIMEOUT|200);
+ int len=so.Read(recvbuff+cnt,-(sizeof(recvbuff)-cnt),200);
if(len>0) {
decr.Decrypt(recvbuff+cnt,recvbuff+cnt,len);
HEXDUMP(L_CC_CCCAM2DT,recvbuff+cnt,len,"net read: len=%d cnt=%d",len,cnt+len);
#include <vdr/pat.h>
#include "cc.h"
-#include "network.h"
#include "parse.h"
// -- cGboxClient -----------------------------------------------------------
class cCardClientGbox : public cCardClient {
private:
- cNetSocket so;
- //
int GetMsg(int cmd, unsigned char *buff, int len);
protected:
virtual bool Login(void);
cCardClientGbox::cCardClientGbox(const char *Name)
:cCardClient(Name)
-,so(DEFAULT_CONNECT_TIMEOUT,2,DEFAULT_IDLE_TIMEOUT,true)
-{}
+{
+ so.SetRWTimeout(2*1000);
+ so.SetUDP(true);
+}
bool cCardClientGbox::Init(const char *config)
{
{
int n;
do {
- n=so.Read(buff,len);
- if(n<=0) {
- if(n==0) PRINTF(L_CC_GBOX,"timeout on GetMsg.");
- break;
- }
+ n=so.Read(buff,-len);
+ if(n<0) break;
} while(buff[0]!=cmd);
return n;
}
SetSctLen(&buff[1],sizeof(pmt)-4+n+4);
buff[2]=(buff[2]&0x0F)|0xB0;
- if(so.SendTo("127.0.0.1",8004,buff,sizeof(pmt)+n+4)<(int)sizeof(pmt)) {
+ if(so.SendTo("127.0.0.1",8004,buff,sizeof(pmt)+n+4)<0) {
PRINTF(L_CC_GBOX,"failed to send PMT data. GBOX running?");
return false;
}
- if((n=GetMsg(0x8a,buff,sizeof(buff)))<=0) {
+ if((n=GetMsg(0x8a,buff,sizeof(buff)))<0) {
PRINTF(L_CC_GBOX,"failed to get ECM port. GBOX running?");
return false;
}
buff[3]=n;
memcpy(&buff[4],data,n);
n+=4;
- if(so.SendTo("127.0.0.1",8005+pidnum,buff,n)<n) {
+ if(so.SendTo("127.0.0.1",8005+pidnum,buff,n)<0) {
PRINTF(L_CC_GBOX,"failed to send ECM data. GBOX running?");
return false;
}
- if(GetMsg(0x89,buff,sizeof(buff))<=0) {
+ if(GetMsg(0x89,buff,sizeof(buff))<0) {
PRINTF(L_CC_GBOX,"failed to get CW. GBOX running?");
return false;
}
#include <vdr/thread.h>
#include "cc.h"
-#include "network.h"
#include "misc.h"
#include "parse.h"
class cCardClientNewCamd : public cCardClient, private cTripleDes, private cIdSet {
private:
- cNetSocket so;
unsigned char configKey[14];
unsigned short netMsgId;
int caId, protoVers, cdLen;
cCardClientNewCamd::cCardClientNewCamd(const char *Name)
:cCardClient(Name)
-,so(DEFAULT_CONNECT_TIMEOUT,20,DEFAULT_IDLE_TIMEOUT)
{
memset(username,0,sizeof(username));
memset(password,0,sizeof(password));
InitVars();
InitProtoVers(525);
+ so.SetRWTimeout(20*1000);
}
void cCardClientNewCamd::InitVars(void)
len+=sizeof(DES_cblock);
netbuf[0]=(len-2)>>8;
netbuf[1]=(len-2)&0xff;
- return cCardClient::SendMsg(&so,netbuf,len);
+ return cCardClient::SendMsg(netbuf,len);
}
int cCardClientNewCamd::ReceiveMessage(unsigned char *data, bool UseMsgId, struct CustomData *cd, comm_type_t commType)
{
unsigned char netbuf[CWS_NETMSGSIZE];
- int len=cCardClient::RecvMsg(&so,netbuf,2);
- if(len!=2) {
- if(len>0) PRINTF(L_CC_NEWCAMD,"bad length %d != 2 on message length read",len);
+ if(cCardClient::RecvMsg(netbuf,2)<0) {
+ PRINTF(L_CC_NEWCAMD,"failed to read message length");
return 0;
}
- const int mlen=WORD(netbuf,0,0xFFFF);
+ int mlen=WORD(netbuf,0,0xFFFF);
if(mlen>CWS_NETMSGSIZE-2) {
PRINTF(L_CC_NEWCAMD,"receive message buffer overflow");
return 0;
}
- len=cCardClient::RecvMsg(&so,netbuf+2,mlen);
- if(len!=mlen) {
- PRINTF(L_CC_NEWCAMD,"bad length %d != %d on message read",len,mlen);
+ if(cCardClient::RecvMsg(netbuf+2,mlen,200)<0) {
+ PRINTF(L_CC_NEWCAMD,"failed to read message");
return 0;
}
- len+=2;
- cTripleDes::Decrypt(netbuf,len); len-=sizeof(DES_cblock);
- if(XorSum(netbuf+2, len-2)) {
+ mlen+=2;
+ cTripleDes::Decrypt(netbuf,mlen); mlen-=sizeof(DES_cblock);
+ if(XorSum(netbuf+2,mlen-2)) {
PRINTF(L_CC_NEWCAMD,"checksum error");
return 0;
}
bool cCardClientNewCamd::CmdSend(net_msg_type_t cmd, comm_type_t commType)
{
unsigned char buffer[3];
- buffer[0] = cmd; buffer[1] = buffer[2] = 0;
+ buffer[0]=cmd; buffer[1]=buffer[2]=0;
return SendMessage(buffer,sizeof(buffer),false,0,commType);
}
InitVars();
unsigned char randData[14];
- if(so.Read(randData,sizeof(randData))!=14) {
+ if(so.Read(randData,sizeof(randData))<0) {
PRINTF(L_CC_NEWCAMD,"no connect answer from %s:%d",hostname,port);
so.Disconnect();
return false;
#include "cc.h"
#include "parse.h"
-#include "network.h"
#include "version.h"
// -- cCardClientRadegast ------------------------------------------------------
class cCardClientRadegast : public cCardClient, private cIdSet {
private:
- cNetSocket so;
bool emmProcessing;
int caids[MAXCAIDS], numCaids;
//
cCardClientRadegast::cCardClientRadegast(const char *Name)
:cCardClient(Name)
-,so(DEFAULT_CONNECT_TIMEOUT,7,DEFAULT_IDLE_TIMEOUT)
{
InitVars();
+ so.SetRWTimeout(7*1000);
}
void cCardClientRadegast::InitVars(void)
bool cCardClientRadegast::Send(const unsigned char *buff)
{
- return SendMsg(&so,buff,GetMsgLength(buff));
+ return SendMsg(buff,GetMsgLength(buff));
}
int cCardClientRadegast::Recv(unsigned char *buff, int len)
{
- int n=RecvMsg(&so,buff,len);
- if(n<1) return n;
- int k=GetNanoStart(buff);
- if(n<k) {
- PRINTF(L_CC_RDGD,"bad length %d < %d on cmd read",n,k);
+ if(RecvMsg(buff,1)<0) {
+ PRINTF(L_CC_RDGD,"short read");
return -1;
}
- k=GetMsgLength(buff);
- if(n<k) {
- PRINTF(L_CC_RDGD,"bad length %d < %d on nano read",n,k);
+ int n=GetNanoStart(buff);
+ if(RecvMsg(buff+1,n-1,200)<0) {
+ PRINTF(L_CC_RDGD,"short read(2)");
return -1;
}
- return n;
+ int k=GetMsgLength(buff);
+ if(RecvMsg(buff+n,k-n,200)<0) {
+ PRINTF(L_CC_RDGD,"short read(3)");
+ return -1;
+ }
+ return k;
}
bool cCardClientRadegast::Login(void)
snprintf(hello,sizeof(hello),"rdgd/vdr-sc-%s",ScVersion);
StartMsg(buff,0x90); // RDGD_MSG_CLIENT_HELLO
AddNano(buff,1,strlen(hello),(unsigned char *)hello); // RDGD_NANO_DESCR
- int n;
- if(!Send(buff) || (n=Recv(buff,sizeof(buff)))<0) return false;
- if(n>0 && buff[0]==0x91) {
+ if(!Send(buff) || Recv(buff,sizeof(buff))<0) return false;
+ if(buff[0]==0x91) {
PRINTF(L_CC_RDGD,"got server hello, assuming V4 mode");
StartMsg(buff,0x94); // RDGD_MSG_CLIENT_CAP_REQ;
+ int n;
if(!Send(buff) || (n=Recv(buff,sizeof(buff)))<0) return false;
- if(n>0 && buff[0]==0x95) {
+ if(buff[0]==0x95) {
LBSTARTF(L_CC_LOGIN);
LBPUT("radegast: got caps");
int caid;
if(!CheckLength(buff,len)) return false;
AddNano(buff,3,len,source); // ECM_NANO_PACKET
- if(!Send(buff) || (len=Recv(buff,sizeof(buff)))<=0) return false;
+ if(!Send(buff) || (len=Recv(buff,sizeof(buff)))<0) return false;
if(buff[0]==2) {
for(int l=GetNanoStart(buff); l<len; l+=buff[l+1]+2) {
switch(buff[l]) {
//
bool Login(void);
public:
- cAuxSrv(void);
int Map(int map, unsigned char *data, int len, int outlen);
};
-cAuxSrv::cAuxSrv(void)
-:so(DEFAULT_CONNECT_TIMEOUT,7,DEFAULT_IDLE_TIMEOUT)
-{}
-
bool cAuxSrv::Login()
{
unsigned char buff[256];
PRINTF(L_SYS_MAP,"auxsrv: connecting to %s:%d",auxAddr,auxPort);
+ so.SetRWTimeout(7000);
if(so.Connect(auxAddr,auxPort)) {
buff[0]=0xA7;
buff[1]=0x7A;
buff[3]=l;
memcpy(&buff[4],auxPassword,l);
buff[4+l]=0xFF;
- if(so.Write(buff,l+5)==l+5 &&
- so.Read(buff,sizeof(buff))>=9 &&
+ if(so.Write(buff,l+5)>0 &&
+ so.Read(buff,9)>0 &&
buff[0]==0x7A && buff[1]==0xA7 && buff[2]==0x00 && buff[3]==0x04 && buff[8]==0xff &&
((buff[4]<<8)|buff[5])==AUX_PROTOCOL_VERSION) return true;
PRINTF(L_SYS_MAP,"auxsrv: login write failed");
buff[4]=map;
memcpy(&buff[5],data,len);
buff[len+5]=0xFF;
- if(so.Write(buff,len+6)==len+6) {
- if((len=so.Read(buff,sizeof(buff)))>0) {
+ if(so.Write(buff,len+6)>0) {
+ if(so.Read(buff,5)>0) {
if(buff[0]==0x7A && buff[1]==0xA7) {
- if(buff[4]==0x00) {
- int cycles=(buff[5]<<16)|(buff[6]<<8)|buff[7];
- int l=buff[2]*256+buff[3];
- if(len>=l+5 && l==outlen+4) {
- if(buff[l+4]==0xFF) {
- memcpy(data,buff+8,outlen);
- return cycles;
+ int l=buff[2]*256+buff[3];
+ if(so.Read(buff+5,l,200)>0) {
+ if(buff[4]==0x00) {
+ int cycles=(buff[5]<<16)|(buff[6]<<8)|buff[7];
+ if(l==outlen+4) {
+ if(buff[l+4]==0xFF) {
+ memcpy(data,buff+8,outlen);
+ return cycles;
+ }
+ else PRINTF(L_SYS_MAP,"auxsrv: bad footer in map%02x response",map);
}
- else PRINTF(L_SYS_MAP,"auxsrv: bad footer in map%02x response",map);
+ else PRINTF(L_SYS_MAP,"auxsrv: bad length in map%02x response (got=%d want=%d)",map,l-4,outlen);
}
- else PRINTF(L_SYS_MAP,"auxsrv: bad length in map%02x response (got=%d,%d want=%d,%d)",map,l-4,len,outlen,l+8);
+ else PRINTF(L_SYS_MAP,"auxsrv: map%02x not successfull (unsupported?)",map);
}
- else PRINTF(L_SYS_MAP,"auxsrv: map%02x not successfull (unsupported?)",map);
+ else PRINTF(L_SYS_MAP,"auxsrv: map%02x read failed (2)",map);
}
else PRINTF(L_SYS_MAP,"auxsrv: bad response to map%02x",map);
}
extern const char *ScVersion;
// SC API version number for loading shared libraries
-#define SCAPIVERS 27
+#define SCAPIVERS 28
#ifndef STATICBUILD
#define SCAPIVERSTAG() int ScLibApiVersion=SCAPIVERS
#else