/** Receive responde from TrendChip CI (sync) */ bool tc_listen () { unsigned short RetRespLen; unsigned char pktBuf[ETH_MAX_SIZE]; if (receivePkt(pktBuf, ETH_MAX_SIZE, &RetRespLen)) { if (RetRespLen == 0) // debugf("-- W: Got empty frame!\n"); { if (dbg_blinkOnReceive) debugf((tc_led = !tc_led) ? "\r." : "\r "); msleep(100); } else { logPkt(true, pktBuf, RetRespLen); pktBuf[RetRespLen] = '\0'; printf("%s", ethResponseToStr(pktBuf)); } } else { debugf("-- Network error (read)\n"); return false; } return true; }
/** Send command to TrendChip CI */ bool tc_exec(char* cmd) { unsigned short i = 0; unsigned char pktBuf[ETH_MAX_SIZE]; char command[TC_CMD_MAX_LEN]; snprintf(command, TC_CMD_MAX_LEN, "%s%s", cmd, TC_LF); unsigned int commandLen = strlen(command); // Set dest MAC memcpy(&pktBuf[i], tc_eth_remoteMac, MAC_LEN); i+=MAC_LEN; // Set source MAC memcpy(&pktBuf[i], tc_eth_localMac, MAC_LEN); i+=MAC_LEN; // Set ETH-TYPE memcpy(&pktBuf[i], TC_ETH_TYPE, sizeof(TC_ETH_TYPE) - 1); i+=(sizeof(TC_ETH_TYPE) - 1); pktBuf[i] = TC_ETHF_REQUEST; i+=1; if (i+commandLen < sizeof(pktBuf)) { debugf("-- Appending data (%d, %d)\n", i, commandLen); memcpy(&pktBuf[i], (unsigned char*)command, commandLen); i+=commandLen; } else { debugf("-- ETH frame overflow (command too long?)\n"); return false; } debugf("-- Sending packet\n"); logPkt(false, pktBuf, i); // Variable 'i' now holds the actual length of pktBuf. bool RetVal = sendPkt(pktBuf, i); if (!RetVal) errorf("-- E: Network error (write)!\n"); return RetVal; }
/***************************************************************************** Send a packet. On entry, req->dest contains the player handle of the recipient or PLAYER_BROADCAST, req->buffer contains the packet to be sent, and req->length contains the number of bytes in the packet. On exit, the buffer may be discarded, although the packet may not be sent until later; resp->status contains the completion status. Return FALSE on error, TRUE otherwise. Note that a TRUE return value does not guarantee that the packet has been (or ever will be) sent. WARNING: ignores req->flags. *****************************************************************************/ DLLEXPORT int cdecl /* success boolean */ commTxPkt( commTxPktReq_t * req, /* input: destination, packet */ commTxPktResp_t * resp) /* output: status */ { commTxPktResp_t respDummy; TCPHANDLE h; DPRINT(("@TCP commTxPkt(): ")); /* Protect against invalid parameters */ assert(req != NULL); assert(req->buffer != NULL); assert(req->length > 0); if (NULL == resp) resp = &respDummy; if ((NULL == req) || (NULL == req->buffer) || (req->length <= 0)) { resp->status = TCP_RES_BAD; return FALSE; } if (!pTcp) { resp->status = comm_STATUS_BUG; return FALSE; } /* Simulate non-broadcast */ #ifndef TCP_LAN if (PLAYER_BROADCAST == req->dest) { resp->status = comm_STATUS_BAD; return FALSE; } #endif logPkt(logpkt_fp, req->buffer, req->length, req->dest, "tx"); /* Send the packet */ h = commHdl2tcp(pTcp, req->dest); resp->status = TCPWIN_PutPacket(pTcp, req->buffer, req->length, h); return (TCP_RES_OK == resp->status); }
/***************************************************************************** Retrieve a pending incoming packet. On entry, req->buffer must point to a block of memory; req->size must be set to the number of bytes in req->buffer. The packet is placed into req->buffer, and the number of bytes actually received is placed in resp->length. Also, resp->src is set to the handle of the player sending the packet. Returns TRUE if a packet was retrieved, FALSE otherwise; resp->status is TCP_RES_OK on success, other values on error. *****************************************************************************/ DLLEXPORT int cdecl /* success boolean */ commRxPkt( commRxPktReq_t *req, /* Non-NULL; input bufsize/output buffer */ commRxPktResp_t *resp) /* output (discarded if NULL) */ { commRxPktResp_t respDummy; int err; TCPHANDLE hTcp; TCPPEER addr; /* DPRINT(("@TCP commRxPkt(): ")); */ /* Protect against invalid parameters */ assert(req != NULL); assert(req->buffer != NULL); assert(req->size > 0); if (NULL == resp) resp = &respDummy; if ((NULL == req) || (NULL == req->buffer) || (req->size <= 0)) { resp->status = TCP_RES_BAD; return FALSE; } if (!pTcp) { resp->status = comm_STATUS_BUG; return FALSE; } /* Retrieve packet */ resp->length = req->size; err = TCPWIN_GetPacket(pTcp, req->buffer, (ULONG *) &resp->length, &hTcp, &addr); if(TCP_RES_OK != err) { resp->status = err; return FALSE; } resp->src = tcp2commHdl(pTcp, hTcp); logPkt(logpkt_fp, req->buffer, resp->length, resp->src, "rx"); /* Handle ping packets immediately */ if ((dp_PING_PACKET_ID == *(dp_packetType_t*)req->buffer) && (TCP_HDL_NONE != hTcp) && (pTcp->myHandle != hTcp)) { *(dp_packetType_t*)req->buffer = dp_PING_RESP_PACKET_ID; logPkt(logpkt_fp, req->buffer, resp->length, resp->src, "tx"); TCPWIN_PutPacket(pTcp, req->buffer, resp->length, hTcp); err = TCP_RES_EMPTY; } /* Ignore packets from myself, save address of unknown senders */ if (PLAYER_ME == resp->src) { err = TCP_RES_EMPTY; } else if (TCP_HDL_NONE == hTcp) { assert(sizeof(TCPPEER) <= comm_MAX_ADR_LEN); memcpy(resp->adr, &addr, sizeof(TCPPEER)); } /* Save status and return */ resp->status = err; return (TCP_RES_OK == err); }