int hu_aap_start (byte ep_in_addr, byte ep_out_addr) { // Starts USB/ACC/OAP, then AA protocol w/ VersReq(1), SSL handshake, Auth Complete if (iaap_state == hu_STATE_STARTED) { loge ("CHECK: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (0); } iaap_state = hu_STATE_STARTIN; logd (" SET: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); int ret = hu_usb_start (ep_in_addr, ep_out_addr); // Start USB/ACC/OAP if (ret) { iaap_state = hu_STATE_STOPPED; logd (" SET: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (ret); // Done if error } byte vr_buf [] = {0, 3, 0, 6, 0, 1, 0, 1, 0, 1}; // Version Request ret = hu_aap_usb_set (0, 3, 1, vr_buf, sizeof (vr_buf)); ret = hu_aap_usb_send (vr_buf, sizeof (vr_buf), 1000); // Send Version Request if (ret < 0) { loge ("Version request send ret: %d", ret); hu_aap_stop (); return (-1); } byte buf [DEFBUF] = {0}; errno = 0; ret = hu_aap_usb_recv (buf, sizeof (buf), 1000); // Get Rx packet from USB: Wait for Version Response if (ret <= 0) { loge ("Version response recv ret: %d", ret); hu_aap_stop (); return (-1); } logd ("Version response recv ret: %d", ret); //* ret = hu_ssl_handshake (); // Do SSL Client Handshake with AA SSL server if (ret) { hu_aap_stop (); return (ret); } byte ac_buf [] = {0, 3, 0, 4, 0, 4, 8, 0}; // Status = OK ret = hu_aap_usb_set (0, 3, 4, ac_buf, sizeof (ac_buf)); ret = hu_aap_usb_send (ac_buf, sizeof (ac_buf), 1000); // Auth Complete, must be sent in plaintext if (ret < 0) { loge ("hu_aap_usb_send() ret: %d", ret); hu_aap_stop (); return (-1); } hu_ssl_inf_log (); iaap_state = hu_STATE_STARTED; logd (" SET: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); //*/ return (0); }
void HUServer::hu_thread_main() { pthread_setname_np(pthread_self(), "hu_thread_main"); int transportFD = transport->GetReadFD(); int errorfd = transport->GetErrorFD(); while(!hu_thread_quit_flag) { fd_set sock_set; FD_ZERO(&sock_set); FD_SET(command_read_fd, &sock_set); FD_SET(transportFD, &sock_set); int maxfd = std::max(command_read_fd, transportFD); if (errorfd >= 0) { maxfd = std::max(maxfd, errorfd); FD_SET(errorfd, &sock_set); } int ret = select(maxfd+1, &sock_set, NULL, NULL, NULL); if (ret <= 0) { loge("Select failed %d", ret); return; } if (errorfd >= 0 && FD_ISSET(errorfd, &sock_set)) { logd("Got errorfd"); hu_thread_quit_flag = true; callbacks.DisconnectionOrError(); } else { if (FD_ISSET(command_read_fd, &sock_set)) { logd("Got command_read_fd"); IHUAnyThreadInterface::HUThreadCommand* ptr = nullptr; if(ptr = hu_pop_command()) { logd("Running %p", ptr); (*ptr)(*this); delete ptr; } } if (FD_ISSET(transportFD, &sock_set)) { //data ready logd("Got transportFD"); ret = hu_aap_recv_process(iaap_tra_recv_tmo); if (ret < 0) { loge("hu_aap_recv_process failed %d", ret); hu_aap_stop(); } } } } logd("hu_thread_main exit"); }
int hu_aap_enc_send (int chan, byte * buf, int len) { // Send encrypted data: type,... if (iaap_state != hu_STATE_STARTED) { loge ("CHECK: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (-1); } if (ena_log_verbo && ena_log_send) { #ifndef NDEBUG hu_aad_dmp ("ES: ", 1, buf, len); #endif } int bytes_written = SSL_write (hu_ssl_ssl, buf, len); // Write plaintext to SSL if (bytes_written <= 0) { loge ("SSL_write() bytes_written: %d", bytes_written); hu_ssl_ret_log (bytes_written); hu_ssl_inf_log (); hu_aap_stop (); return (-1); } if (bytes_written != len) loge ("SSL_write() len: %d bytes_written: %d chan: %d", len, bytes_written, chan); else if (ena_log_verbo && ena_log_send) logd ("SSL_write() len: %d bytes_written: %d chan: %d", len, bytes_written, chan); int bytes_read = BIO_read (hu_ssl_wm_bio, & enc_buf [4], sizeof (enc_buf) - 4); // Read encrypted from SSL BIO to enc_buf if (bytes_read <= 0) { loge ("BIO_read() bytes_read: %d", bytes_read); hu_aap_stop (); return (-1); } if (ena_log_verbo && ena_log_send) logd ("BIO_read() bytes_read: %d", bytes_read); int flags = 0x0b; // Flags = First + Last + Encrypted if (chan != 0 && buf [0] == 0) { // If msg_type = 0 - 255 flags = 0x0f; // Control //logd ("Setting control"); } hu_aap_usb_set (chan, flags, -1, enc_buf, bytes_read + 4); // -1 for type so encrypted type position is not overwritten !! hu_aap_usb_send (enc_buf, bytes_read + 4, iaap_send_tmo); // Send encrypted data to AA Server return (0); }
int HUServer::hu_handle_VersionResponse (int chan, byte * buf, int len) { logd ("Version response recv len: %d", len); hex_dump("version", 40, buf, len); int ret = hu_ssl_begin_handshake (); // Do SSL Client Handshake with AA SSL server if (ret) { hu_aap_stop (); } return (ret); }
int aa_pro_all_a0f (int chan, byte * buf, int len) { logd ("Byebye all chan: %d", chan); int ret = hu_aap_enc_send (chan, bye_rsp, sizeof (bye_rsp)); // Respond with Byebye rsp ms_sleep (100); // Wait for response //terminate = 1; hu_aap_stop (); return (-1); }
int jni_aa_cmd (int cmd_len, char * cmd_buf, int res_max, char * res_buf) { if (ena_log_extra || cmd_len >= 1) logd ("cmd_len: %d cmd_buf %p res_max: %d res_buf: %p", cmd_len, cmd_buf, res_max, res_buf); int res_len = 0; int ret = 0; if (cmd_buf != NULL && cmd_len == 3 && cmd_buf [0] == 121) { // If onCreate() hu_tra:transport_start() byte ep_in_addr = cmd_buf [1]; byte ep_out_addr = cmd_buf [2]; ret = hu_aap_start (ep_in_addr, ep_out_addr); // Start USB/ACC/OAP, AA Protocol aap_state_starts ++; // Count error starts too if (ret == 0) { logd ("hu_aap_start() success aap_state_starts: %d", aap_state_starts); } else { loge ("hu_aap_start() error aap_state_starts: %d", aap_state_starts); aap_state_start_error = 1; return (-1); } } if (cmd_buf != NULL && cmd_len >= 4) { // If encrypted command to send... int chan = cmd_buf [0]; ret = hu_aap_enc_send (chan, & cmd_buf [4], cmd_len - 4); // Send if (cmd_buf != NULL && cmd_len >= 8 && cmd_buf [5] == 15) { // If byebye... loge ("Byebye"); ms_sleep (100); ret = hu_aap_stop (); } } else { ret = hu_aap_recv_process (); // Process 1 message } if (ret < 0) { return (ret); } byte * dq_buf = read_head_buffer_get (& res_len); if (ena_log_extra || (ena_log_verbo && dq_buf != NULL)) logd ("dq_buf: %p", dq_buf); if (dq_buf == NULL || res_len <= 0) { if (ena_log_extra) logd ("No data dq_buf: %p res_len: %d", dq_buf, res_len); return (0); } memcpy (res_buf, dq_buf, res_len); if (ena_log_verbo) logd ("res_len: %d", res_len); return (res_len); }
int hu_aap_usb_recv (byte * buf, int len, int tmo) { int ret = 0; if (iaap_state != hu_STATE_STARTED && iaap_state != hu_STATE_STARTIN) { // Need to recv when starting loge ("CHECK: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (-1); } ret = hu_usb_recv (buf, len, tmo); if (ret < 0) { loge ("hu_usb_recv() error so stop USB & AAP ret: %d", ret); hu_aap_stop (); } return (ret); }
int HUServer::hu_aap_tra_recv (byte * buf, int len, int tmo) { int ret = 0; if (iaap_state != hu_STATE_STARTED && iaap_state != hu_STATE_STARTIN) { // Need to recv when starting loge ("CHECK: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (-1); } int readfd = transport->GetReadFD(); int errorfd = transport->GetErrorFD(); if (tmo > 0 || errorfd >= 0) { fd_set sock_set; FD_ZERO(&sock_set); FD_SET(readfd, &sock_set); int maxfd = readfd; if (errorfd >= 0) { maxfd = std::max(maxfd, errorfd); FD_SET(errorfd, &sock_set); } timeval tv_timeout; tv_timeout.tv_sec = tmo / 1000; tv_timeout.tv_usec = tmo * 1000; int ret = select(maxfd+1, &sock_set, NULL, NULL, (tmo > 0) ? &tv_timeout : NULL); if (ret < 0) { return ret; } else if (errorfd >= 0 && FD_ISSET(errorfd, &sock_set)) { //got an error loge("errorf was signaled"); return -1; } else if (ret == 0) { loge("hu_aap_tra_recv Timeout"); return -1; } } ret = read(readfd, buf, len); if (ret < 0) { loge ("ihu_tra_recv() error so stop Transport & AAP ret: %d", ret); hu_aap_stop (); } return (ret); }
int HUServer::hu_handle_ShutdownRequest (int chan, byte * buf, int len) { // Byebye Request HU::ShutdownRequest request; if (!request.ParseFromArray(buf, len)) loge ("Byebye Request"); else if (request.reason() == 1) logd ("Byebye Request reason: 1 AA Exit Car Mode"); else loge ("Byebye Request reason: %d", request.reason()); HU::ShutdownResponse response; hu_aap_enc_send_message(0, chan, HU_PROTOCOL_MESSAGE::ShutdownResponse, response); ms_sleep (100); // Wait a bit for response hu_aap_stop (); return (-1); }
int hu_aap_usb_send (byte * buf, int len, int tmo) { // Send USB data: chan,flags,len,type,... if (iaap_state != hu_STATE_STARTED && iaap_state != hu_STATE_STARTIN) { // Need to send when starting loge ("CHECK: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (-1); } if (ena_log_verbo && ena_log_send) { #ifndef NDEBUG if (buf [1] | 0x08 == 0) // If not encrypted (which was dumped in hu_aap_enc_send() hu_aad_dmp ("US: ", 1, & buf [4], len - 4); #endif } int ret = hu_usb_send (buf, len, tmo); if (ret < 0 || ret != len) { loge ("Error hu_usb_send() error so stop USB & AAP ret: %d len: %d", ret, len); hu_aap_stop (); return (-1); } if (ena_log_verbo && ena_log_send) logd ("OK hu_usb_send() ret: %d len: %d", ret, len); return (ret); }
int HUServer::hu_aap_tra_send (int retry, byte * buf, int len, int tmo) { // Send Transport data: chan,flags,len,type,... // Need to send when starting if (iaap_state != hu_STATE_STARTED && iaap_state != hu_STATE_STARTIN) { loge ("CHECK: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (-1); } int ret = transport->Write(buf, len, tmo); if (ret < 0 || ret != len) { if (retry == 0) { loge ("Error ihu_tra_send() error so stop Transport & AAP ret: %d len: %d", ret, len); hu_aap_stop (); } return (-1); } if (ena_log_verbo && ena_log_aap_send) logd ("OK ihu_tra_send() ret: %d len: %d", ret, len); return (ret); }
int HUServer::hu_aap_enc_send (int retry,int chan, byte * buf, int len, int overrideTimeout) { // Encrypt data and send: type,... if (iaap_state != hu_STATE_STARTED) { logw ("CHECK: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); //logw ("chan: %d len: %d buf: %p", chan, len, buf); //hex_dump (" W/ hu_aap_enc_send: ", 16, buf, len); // Byebye: hu_aap_enc_send: 00000000 00 0f 08 00 return (-1); } byte base_flags = HU_FRAME_ENCRYPTED; uint16_t message_type = be16toh(*((uint16_t*)buf)); if (chan != AA_CH_CTR && message_type >= 2 && message_type < 0x8000) { // If not control channel and msg_type = 0 - 255 = control type message base_flags |= HU_FRAME_CONTROL_MESSAGE; // Set Control Flag (On non-control channels, indicates generic/"control type" messages //logd ("Setting control"); } for (int frag_start = 0; frag_start < len; frag_start += MAX_FRAME_PAYLOAD_SIZE) { byte flags = base_flags; if (frag_start == 0) { flags |= HU_FRAME_FIRST_FRAME; } int cur_len = MAX_FRAME_PAYLOAD_SIZE; if ((frag_start + MAX_FRAME_PAYLOAD_SIZE) >= len) { flags |= HU_FRAME_LAST_FRAME; cur_len = len - frag_start; } #ifndef NDEBUG // if (ena_log_verbo && ena_log_aap_send) { if (log_packet_info) { // && ena_log_aap_send) char prefix [MAX_FRAME_SIZE] = {0}; snprintf (prefix, sizeof (prefix), "S %d %s %1.1x", chan, chan_get (chan), flags); // "S 1 VID B" int rmv = hu_aad_dmp (prefix, "HU", chan, flags, &buf[frag_start], cur_len); } #endif int bytes_written = SSL_write (hu_ssl_ssl, &buf[frag_start], cur_len); // Write plaintext to SSL if (bytes_written <= 0) { loge ("SSL_write() bytes_written: %d", bytes_written); hu_ssl_ret_log (bytes_written); hu_ssl_inf_log (); hu_aap_stop (); return (-1); } if (bytes_written != cur_len) loge ("SSL_write() cur_len: %d bytes_written: %d chan: %d %s", cur_len, bytes_written, chan, chan_get (chan)); else if (ena_log_verbo && ena_log_aap_send) logd ("SSL_write() cur_len: %d bytes_written: %d chan: %d %s", cur_len, bytes_written, chan, chan_get (chan)); enc_buf [0] = (byte) chan; // Encode channel and flags enc_buf [1] = flags; int header_size = 4; if ((flags & HU_FRAME_FIRST_FRAME) & !(flags & HU_FRAME_LAST_FRAME)) { //write total len *((uint32_t*)&enc_buf[header_size]) = htobe32(len); header_size += 4; } int bytes_read = BIO_read (hu_ssl_wm_bio, & enc_buf [header_size], sizeof (enc_buf) - header_size); // Read encrypted from SSL BIO to enc_buf + if (bytes_read <= 0) { loge ("BIO_read() bytes_read: %d", bytes_read); hu_aap_stop (); return (-1); } if (ena_log_verbo && ena_log_aap_send) logd ("BIO_read() bytes_read: %d", bytes_read); *((uint16_t*)&enc_buf[2]) = htobe16(bytes_read); int ret = 0; ret = hu_aap_tra_send (retry, enc_buf, bytes_read + header_size, overrideTimeout < 0 ? iaap_tra_send_tmo : overrideTimeout); // Send encrypted data to AA Server if (retry) return (ret); } return (0); }
int jni_aa_cmd (int cmd_len, char * cmd_buf, int res_max, char * res_buf) { if (ena_log_extra || cmd_len >= 1) logd ("cmd_len: %d cmd_buf %p res_max: %d res_buf: %p", cmd_len, cmd_buf, res_max, res_buf); int res_len = 0; int ret = 0; int vid_bufs = vid_buf_buf_tail - vid_buf_buf_head; int aud_bufs = vid_buf_buf_tail - vid_buf_buf_head; if (cmd_buf != NULL && cmd_len == 3 && cmd_buf [0] == 121) { // If onCreate() hu_tra:transport_start() byte ep_in_addr = cmd_buf [1]; byte ep_out_addr = cmd_buf [2]; // Get endpoints passed ret = hu_aap_start (ep_in_addr, ep_out_addr); // Start USB/ACC/OAP, AA Protocol aap_state_starts ++; // Count error starts too if (ret == 0) { logd ("hu_aap_start() success aap_state_starts: %d", aap_state_starts); } else { loge ("hu_aap_start() error aap_state_starts: %d", aap_state_starts); aap_state_start_error = 1; return (-1); } } /* Functions code Params: Transport Start hu_aap_start() USB EPs Poll/Handle 1 Rcv Msg hu_aap_recv_process() - Send: Send Mic hu_aap_enc_send() mic data Send Touch hu_aap_enc_send() touch data Send Ctrl hu_aap_enc_send()/hu_aap_stop() ctrl data Returns: Audio Mic Start/Stop Audio Out Start/Stop Video Audio */ else if (cmd_buf != NULL && cmd_len >= 4) { // If encrypted command to send... int chan = 0;//cmd_buf [0]; if (cmd_len > 63) // If Microphone audio... chan = AA_CH_MIC; else if (cmd_len > 6 && cmd_buf [4] == 0x80 && cmd_buf [5] == 1) // If Touch event... chan = AA_CH_TOU; else // If Byebye or other control packet... chan = AA_CH_CTR; if (chan != cmd_buf [0]) { loge ("chan: %d != cmd_buf[0]: %d", chan, cmd_buf [0]); chan = cmd_buf [0]; } //hex_dump ("JNITX: ", 16, cmd_buf, cmd_len); ret = hu_aap_enc_send (chan, & cmd_buf [4], cmd_len - 4); // Send if (cmd_buf != NULL && cmd_len >= 8 && cmd_buf [5] == 15) { // If byebye... logd ("Byebye"); ms_sleep (100); ret = hu_aap_stop (); } } else { if (vid_bufs > 0 || aud_bufs > 0) // If any queue audio or video... ret = 0; // Do nothing (don't wait for recv iaap_tra_recv_tmo) else ret = hu_aap_recv_process (); // Else Process 1 message w/ iaap_tra_recv_tmo } if (ret < 0) { return (ret); // If error then done w/ error } if (vid_bufs <= 0 && aud_bufs <= 0) { // If no queued audio or video... ret = hu_aap_mic_get (); if (ret >= 1) {// && ret <= 2) { // If microphone start (2) or stop (1)... return (ret); // Done w/ mic notification: start (2) or stop (1) } // Else if no microphone state change... if (hu_aap_out_get (AA_CH_AUD) >= 0) // If audio out stop... return (3); // Done w/ audio out notification 0 if (hu_aap_out_get (AA_CH_AU1) >= 0) // If audio out stop... return (4); // Done w/ audio out notification 1 if (hu_aap_out_get (AA_CH_AU2) >= 0) // If audio out stop... return (5); // Done w/ audio out notification 2 } byte * dq_buf = NULL; dq_buf = aud_read_head_buf_get (& res_len); // Get audio if ready if (dq_buf == NULL) // If no audio... (Audio has priority over video) dq_buf = vid_read_head_buf_get (& res_len); // Get video if ready else { // If audio if (dq_buf [0] == 0 && dq_buf [1] == 0 && dq_buf [2] == 0 && dq_buf [3] == 1) { dq_buf [3] = 0; // If audio happened to have magic video signature... (rare), then 0 the 1 loge ("magic video signature in audio"); } //hu_uti.c: #define aud_buf_BUFS_SIZE 65536 * 4 // Up to 256 Kbytes } if (ena_log_extra || (ena_log_verbo && dq_buf != NULL)) logd ("dq_buf: %p", dq_buf); if (dq_buf == NULL || res_len <= 0) { if (ena_log_extra) logd ("No data dq_buf: %p res_len: %d", dq_buf, res_len); return (0); } memcpy (res_buf, dq_buf, res_len); if (ena_log_verbo) logd ("res_len: %d", res_len); return (res_len); }
int main (int argc, char *argv[]) { signal (SIGTERM, signals_handler); gst_app_t *app = &gst_app; int ret = 0; errno = 0; byte ep_in_addr = -2; byte ep_out_addr = -2; /* Init gstreamer pipeline */ ret = gst_pipeline_init(app); if (ret < 0) { printf("gst_pipeline_init() ret: %d\n", ret); return (-4); } /* Start AA processing */ ret = hu_aap_start (ep_in_addr, ep_out_addr); if (ret == -1) { printf("Phone switched to accessory mode. Attempting once more.\n"); sleep(1); ret = hu_aap_start (ep_in_addr, ep_out_addr); } if (ret < 0) { if (ret == -2) printf("Phone is not connected. Connect a supported phone and restart.\n"); else if (ret == -1) printf("Phone switched to accessory mode. Restart to enter AA mode.\n"); else printf("hu_app_start() ret: %d\n", ret); return (ret); } printf("Starting Android Auto...\n"); /* Open Touchscreen Device */ mTouch.fd = open(EVENT_DEVICE_TS, O_RDONLY); if (mTouch.fd == -1) { fprintf(stderr, "%s is not a vaild device\n", EVENT_DEVICE_TS); return -3; } /* Open Commander Device */ mCommander.fd = open(EVENT_DEVICE_CMD, O_RDONLY); if (mCommander.fd == -1) { fprintf(stderr, "%s is not a vaild device\n", EVENT_DEVICE_CMD); return -3; } sendqueue = g_async_queue_new(); pthread_t iput_thread; pthread_create(&iput_thread, NULL, &input_thread, (void *)app); pthread_t nm_thread; pthread_create(&nm_thread, NULL, &nightmode_thread, (void *)app); pthread_t mn_thread; pthread_create(&mn_thread, NULL, &main_thread, (void *)app); /* Start gstreamer pipeline and main loop */ ret = gst_loop(app); if (ret < 0) { printf("gst_loop() ret: %d\n", ret); ret = -5; } /* Stop AA processing */ ret = hu_aap_stop (); if (ret < 0) { printf("hu_aap_stop() ret: %d\n", ret); ret = -6; } close(mTouch.fd); close(mCommander.fd); pthread_cancel(nm_thread); pthread_cancel(mn_thread); pthread_cancel(iput_thread); printf("END \n"); return (ret); }
int hu_aap_recv_process () { // Process 1 encrypted receive message set, from reading encrypted message from USB to reacting to decrypted message if (iaap_state != hu_STATE_STARTED && iaap_state != hu_STATE_STARTIN) { // Need to recv when starting) { loge ("CHECK: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (-1); } byte * buf = rx_buf; int ret = 0; errno = 0; int len_remain = hu_aap_usb_recv (rx_buf, sizeof (rx_buf), iaap_recv_tmo); // Get Rx packet from USB // Length remaining for all sub-packets plus 4/8 byte headers if (len_remain == 0) { // If no data, then done w/ no data return (0); } if (len_remain < 0) { loge ("Recv len_remain: %d", len_remain); hu_aap_stop (); return (-1); } int ctr = 0; while (len_remain > 0) { // While length remaining,... Process Rx packet: //if (ctr ++ > 0) // Multiple subpackets work OK now // loge ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); if (ena_log_verbo) { logd ("Recv while (len_remain > 0): %d", len_remain); #ifndef NDEBUG hex_dump ("LR: ", 16, buf, len_remain); #endif } /*if (len_remain % 16384 == 0) { // Incomplete 16K packets don't happen now with 64K USB Rx buffers loge ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); loge ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); loge ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); }*/ int chan = (int) buf [0]; // Channel int flags = buf [1]; // Flags int len = (int) buf [3]; // Encoded length of bytes to be decrypted (minus 4/8 byte headers) len += ((int) buf [2] * 256); int type = (int) buf [5]; // Message Type (or post handshake, mostly indicator of SSL encrypted data) type += ((int) buf [4] * 256); len_remain -= 4; // Length starting at byte 4: Unencrypted Message Type or Encrypted data start buf += 4; // buf points to data to be decrypted if (chan == AA_CH_VID && flags == 9) { // If First fragment Video... Packet is encrypted so we can't get the real msg_type or check for 0, 0, 0, 1 int total_size = (int) buf [3]; total_size += ((int) buf [2] * 256); total_size += ((int) buf [1] * 256 * 256); total_size += ((int) buf [0] * 256 * 256 * 256); if (max_assy_size < total_size) // Seen as big as 151 Kbytes so far max_assy_size = total_size; // See: jni/hu_aap.c: byte assy [65536 * 16] = {0}; // up to 1 megabyte loge ("First fragment total_size: %d max_assy_size: %d", total_size, max_assy_size); // & jni/hu_uti.c: #define gen_buf_BUFS_SIZE 65536 * 4 // Up to 256 Kbytes // & src/ca/yyx/hu/hu_tro.java: byte [] assy = new byte [65536 * 16]; // & src/ca/yyx/hu/hu_tra.java: res_buf = new byte [65536 * 4]; len_remain -= 4; // Remove 4 length bytes inserted into first video fragment buf += 4; } if (flags & 0x08 != 0x08) { loge ("NOT ENCRYPTED !!!!!!!!! len_remain: %d len: %d buf: %p chan: %d flags: 0x%x type: %d", len_remain, len, buf, chan, flags, type); hu_aap_stop (); return (-1); } if (len_remain < len) { int need = len - len_remain; logd ("len_remain: %d < len: %d need: %d !!!!!!!!!", len_remain, len, need); //ms_sleep (50); // ?? Wait a bit for data to come ?? int need_ret = hu_aap_usb_recv (& buf [len_remain], need, iaap_recv_tmo); // Get Rx packet from USB // Length remaining for all sub-packets plus 4/8 byte headers if (need_ret != need) { loge ("Recv need_ret: %d", need_ret); hu_aap_stop (); return (-1); } len_remain = len; } ret = iaap_recv_dec_process (chan, flags, buf, len); // Decrypt & Process 1 received encrypted message if (ret < 0) { loge ("Error iaap_recv_dec_process() ret: %d len_remain: %d len: %d buf: %p chan: %d flags: 0x%x type: %d", ret, len_remain, len, buf, chan, flags, type); hu_aap_stop (); return (ret); } logd ("OK iaap_recv_dec_process() ret: %d len_remain: %d len: %d buf: %p chan: %d flags: 0x%x type: %d", ret, len_remain, len, buf, chan, flags, type); len_remain -= len; // Consume processed sub-packet and advance to next, if any buf += len; } return (ret); // Return from the last; should be 0 }