BOOL PSConfig(HANDLE hPort) { int iDelay; BOOL bLastSentPacket; unsigned char chActivity = 0; unsigned char chSendBuffer[512], chReceiveBuffer[512]; struct ubcsp_packet SendPacket, ReceivePacket; giPDUIndex = 0; giResetSent = 0; DebugMessage(1,(_T("++PSConfig++ Enter\r\n"))); // Construct pdus ghPort = hPort; FILE *stream; stream = fopen(gchFileName, "r"); if(stream) { DebugMessage(1,(_T("PSConfig: open PSConfig.psr file, line = %d\r\n"),__LINE__)); // Count entries giPDUCount = 0; giPDUCount = ReadPSRFile(stream, false); // Count only if(giPDUCount == 0) { DebugMessage(1,(_T("++ERROR++:: PSConfig++ PSR file No data \r\n"))); return FALSE; // No data } gPDU = new BCCMDPDU[giPDUCount + 1]; // Last pdu is warm reset // gPDU = (BCCMDPDU*)malloc(sizeof(BCCMDPDU)); if(!gPDU) { DebugMessage(1,(_T("new BCCMDPDU[giPDUCount + 1] error %d\r\n"),__LINE__)); } fseek(stream, 0, SEEK_SET); // Seek start of stream giPDUCount = 0; // Reset to zero and load pdu array ReadPSRFile(stream, true); // Adds .psr file pdu's giPDUCount++; // Extra reset pdu ConfigResetPDU(); // Construct Reset PDU // Close file fclose(stream); } else { DebugMessage(1,(_T("++ERROR++:: PSConfig++ Can not open PSR file.\r\n"))); return FALSE; // File access problem } // Setup packets payload SendPacket.payload = chSendBuffer; ReceivePacket.payload = chReceiveBuffer; ReceivePacket.length = 512; // Ask ubcsp to receive a packet ubcsp_initialize(); ubcsp_receive_packet (&ReceivePacket); uBCSP_TXQueue.CommandNumber = RECEIVED_STATE; uBCSP_TXQueue.NoOfOpcodes = 0; uBCSP_TXQueue.NoOfRetries = 0; // Start Link establishment timer giStartTime = GetTickCount(); // Reset packet counter bLastSentPacket = FALSE; // Enter loop to 'listen' to uBCSP commands while(TRUE) { switch(uBCSP_TXQueue.CommandNumber) { case POLL_STATE: { // if(icount >= 9) // DebugMessage(1,(_T("++PSConfig++:: POLL_STATE.\r\n"))); // Poll uBCSP for activity iDelay = ubcsp_poll (&chActivity); uBCSP_TXQueue.CommandNumber = RECEIVED_STATE; // Link Init check if((GetTickCount() - giStartTime > LINKTIMEOUT) && !gbLinked) uBCSP_TXQueue.CommandNumber = EXIT_STATE; if(ubcsp_config.link_establishment_state > 0) gbLinked = TRUE; } break; case RECEIVED_STATE: { // DebugMessage(1,(_T("++PSConfig++:: RECEIVED_STATE.\r\n"))); uBCSP_TXQueue.CommandNumber = PEER_RESET_STATE; if(chActivity & UBCSP_PACKET_RECEIVED) { DebugMessage(1,(_T("++PSConfig++:: UBCSP_PACKET_RECEIVED\r\n"))); GetReceiveState(&ReceivePacket, chReceiveBuffer); } if(chActivity & UBCSP_PACKET_SENT) { // Acknowledge sent package DebugMessage(1,(_T("++PSConfig++:: UBCSP_PACKET_SENT icount=%d\r\n"),icount)); // if(icount == 10) // uBCSP_TXQueue.CommandNumber = EXIT_STATE; icount++; if(!bLastSentPacket) { // Link is established DebugMessage(1,(_T("++PSConfig++:: Link is now Established\r\n"))); uBCSP_TXQueue.CommandNumber = SENT_STATE; } bLastSentPacket = TRUE; } // DebugMessage(1,(_T("++PSConfig++:: RECEIVED_STATE chActivity =0x%x.\r\n"),chActivity)); } break; case SENT_STATE: { // DebugMessage(1,(_T("++PSConfig++:: SENT_STATE.\r\n"))); // Returns the appropriate next state GetSentState(&SendPacket); } break; case PEER_RESET_STATE: { //DebugMessage(1,(_T("++PSConfig++:: PEER_RESET_STATE.\r\n"))); if((chActivity & UBCSP_PEER_RESET) && giResetSent > 0) { // Peer reset detected DebugMessage(1, (_T("++PSConfig++:: uBCSP PEER RESET RECEIVED.\r\n"))); uBCSP_TXQueue.CommandNumber = EXIT_STATE; break; } uBCSP_TXQueue.CommandNumber = SLEEP_STATE; } break; case SLEEP_STATE: { // DebugMessage(1,(_T("++PSConfig++:: SLEEP_STATE. sleep %d\r\n"),iDelay)); if(iDelay) { // If we need to delay, sleep for minimum period Sleep(1); } uBCSP_TXQueue.CommandNumber = POLL_STATE; } break; case EXIT_STATE: { DebugMessage(1,(_T("++PSConfig++:: EXIT_STATE.\r\n"))); // Exit module ExitMod(); return TRUE; } break; }//endof switch }//endof while return TRUE; }
int csr_open_bcsp(char *device) { struct termios ti; uint8_t delay, activity = 0x00; int timeout = 0; if (!device) device = "/dev/ttyS0"; fd = open(device, O_RDWR | O_NOCTTY); if (fd < 0) { fprintf(stderr, "Can't open serial port: %s (%d)\n", strerror(errno), errno); return -1; } tcflush(fd, TCIOFLUSH); if (tcgetattr(fd, &ti) < 0) { fprintf(stderr, "Can't get port settings: %s (%d)\n", strerror(errno), errno); close(fd); return -1; } cfmakeraw(&ti); ti.c_cflag |= CLOCAL; ti.c_cflag &= ~CRTSCTS; ti.c_cflag |= PARENB; ti.c_cflag &= ~PARODD; ti.c_cflag &= ~CSIZE; ti.c_cflag |= CS8; ti.c_cflag &= ~CSTOPB; ti.c_cc[VMIN] = 1; ti.c_cc[VTIME] = 0; cfsetospeed(&ti, B38400); if (tcsetattr(fd, TCSANOW, &ti) < 0) { fprintf(stderr, "Can't change port settings: %s (%d)\n", strerror(errno), errno); close(fd); return -1; } tcflush(fd, TCIOFLUSH); if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) < 0) { fprintf(stderr, "Can't set non blocking mode: %s (%d)\n", strerror(errno), errno); close(fd); return -1; } memset(&send_packet, 0, sizeof(send_packet)); memset(&receive_packet, 0, sizeof(receive_packet)); ubcsp_initialize(); send_packet.length = 512; send_packet.payload = send_buffer; receive_packet.length = 512; receive_packet.payload = receive_buffer; ubcsp_receive_packet(&receive_packet); while (1) { delay = ubcsp_poll(&activity); if (activity & UBCSP_PACKET_RECEIVED) break; if (delay) { usleep(delay * 100); if (timeout++ > 5000) { fprintf(stderr, "Initialization timed out\n"); return -1; } } } return 0; }
void GetReceiveState(struct ubcsp_packet *rx_packet, unsigned char *rx_buffer) { // DebugMessage(1,(_T("++GetReceiveState++:: Enter =.\r\n"))); // Only print out BCCMD information if(rx_packet->channel == BCCMD) { switch(rx_buffer[0] & 0xFF) { case 0x01: { DebugMessage(1,(_T("++GetReceiveState++:: BCCMD COMMAND RECEIVED =.\r\n"))); PrintData(rx_buffer, rx_packet->length); // Check to see if Command Complete is the PS from TX Queue // If it is allow next BCCMD Message if(((rx_buffer[6] & 0xFF) == uBCSP_TXQueue.Opcode[0]) && ((rx_buffer[7] & 0xFF) == uBCSP_TXQueue.Opcode[1])) { DebugMessage(1,(_T("++GetReceiveState++:: COMMAND COMPLETE =.\r\n"))); uBCSP_TXQueue.CommandNumber = SENT_STATE; uBCSP_TXQueue.NoOfOpcodes = 0; } else { DebugMessage(1,(_T("++GetReceiveState _WARNING++:: COMMAND DOES NOT MATCH QUEUE.\r\n"))); } } break; case 0x05: { // Output to Debug any disconnection attempts DebugMessage(1,(_T("++GetReceiveState++:: DISCONNECTION COMPLETE =.\r\n"))); PrintData(rx_buffer, rx_packet->length); } break; case 0x10: { // Output to Debug any detected error messages DebugMessage(1,(_T("++GetReceiveState_WARNING++:: HARDWARE ERROR =.\r\n"))); PrintData(rx_buffer, rx_packet->length); } break; case 0x0f: { DebugMessage(1,(_T("COMMAND STATUS.\r\n"))); PrintData(rx_buffer, rx_packet->length); } break; default: { // Output to Debug any other message // OutputDebugString("\nUNKNOWN COMMAND: "); // PrintData(rx_buffer, rx_packet->length); } } } else { // Reset received if(rx_packet->channel == HCI_COMMAND && (rx_buffer[0] & 0xFF) == 0x0f ) { if(giPDUIndex == giPDUCount) { DebugMessage(1,(_T("++GetReceiveState++::...Reset complete....\r\n"))); uBCSP_TXQueue.CommandNumber = EXIT_STATE; } } else { // Check any data received on other channels // OutputDebugString("\n|_WARNING: DATA RECEIVED ON NON BCCMD CHANNEL:"); // sprintf(sTemp, "\n|_Packet Received, Channel = %02x ", rx_packet->channel); // OutputDebugString(sTemp); // OutputDebugString("\n|_Data: "); // PrintData(rx_buffer, rx_packet->length); } } // Allow another packet to be received up to 512 bytes long rx_packet->length = 512; memset(rx_packet->payload, 0, 512); // Setup the receive again ubcsp_receive_packet(rx_packet); }
static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { unsigned char cp[254], rp[254]; uint8_t cmd[10]; uint16_t size; uint8_t delay, activity = 0x00; int timeout = 0, sent = 0; size = (length < 8) ? 9 : ((length + 1) / 2) + 5; cmd[0] = command & 0xff; cmd[1] = command >> 8; cmd[2] = size & 0xff; cmd[3] = size >> 8; cmd[4] = seqnum & 0xff; cmd[5] = seqnum >> 8; cmd[6] = varid & 0xff; cmd[7] = varid >> 8; cmd[8] = 0x00; cmd[9] = 0x00; memset(cp, 0, sizeof(cp)); cp[0] = 0x00; cp[1] = 0xfc; cp[2] = (size * 2) + 1; cp[3] = 0xc2; memcpy(cp + 4, cmd, sizeof(cmd)); memcpy(cp + 14, value, length); receive_packet.length = 512; ubcsp_receive_packet(&receive_packet); send_packet.channel = 5; send_packet.reliable = 1; send_packet.length = (size * 2) + 4; memcpy(send_packet.payload, cp, (size * 2) + 4); ubcsp_send_packet(&send_packet); while (1) { delay = ubcsp_poll(&activity); if (activity & UBCSP_PACKET_SENT) { switch (varid) { case CSR_VARID_COLD_RESET: case CSR_VARID_WARM_RESET: case CSR_VARID_COLD_HALT: case CSR_VARID_WARM_HALT: return 0; } sent = 1; timeout = 0; } if (activity & UBCSP_PACKET_RECEIVED) { if (sent && receive_packet.channel == 5 && receive_packet.payload[0] == 0xff) { memcpy(rp, receive_packet.payload, receive_packet.length); break; } receive_packet.length = 512; ubcsp_receive_packet(&receive_packet); timeout = 0; } if (delay) { usleep(delay * 100); if (timeout++ > 5000) { fprintf(stderr, "Operation timed out\n"); return -1; } } } if (rp[0] != 0xff || rp[2] != 0xc2) { errno = EIO; return -1; } if ((rp[11] + (rp[12] << 8)) != 0) { errno = ENXIO; return -1; } memcpy(value, rp + 13, length); return 0; }