CARPLAY版本整理

This commit is contained in:
2025-01-21 16:49:37 +08:00
commit f0fb64e4e6
26542 changed files with 13719676 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,124 @@
#ifndef _ANDROID_AUTO_H_H
#define _ANDROID_AUTO_H_H
typedef enum
{
LINK_UNSUPPORTED= 0xff,
LINK_CONNECTED = 1,
LINK_DISCONNECTED = 2,
LINK_STARTING = 3,
LINK_SUCCESS = 4,
LINK_FAIL = 5,
LINK_EXITING = 6,
LINK_EXITED = 7 ,
LINK_REMOVED = 8,
LINK_INSERTED = 9,
LINK_NOT_INSERTED = 10,
LINK_NOT_INSTALL = 11,
LINK_CALL_PHONE = 12,
LINK_CALL_PHONE_EXITED = 13,
LINK_MUTE =14,
LINK_UNMUTE = 15,
LINK_NODATA = 16,
LINK_VIDEOREADY = 17,
LINK_BT_DISCONNECT = 18,
LINK_FAILED_EAP = 19,
LINK_FAILED_UNSTART = 20,
LINK_AUTO_BT_UNPAIRED = 21,
LINK_AUTO_BT_PAIRED = 22,
LINK_AUTO_BT_REQUEST = 23,
LINK_EXIT_PROCESS = 24,
LINK_KILL_PROCESS = 25,
LINK_SOCKET_TRUST = 26,
LINK_OPEN_CARLIFE = 27,
LINK_VOLUME_START = 28,
LINK_VOLUME_STOP = 29,
LINK_RECONNECT = 30,
LINK_ILLLIGHT_ON = 31,
LINK_ILLLIGHT_OFF = 32,
LINK_SIRI_START = 33,
LINK_SIRI_STOP = 34,
LINK_ASSIST_START = 35,
LINK_ASSIST_STOP = 36,
LINK_TEL_START = 37,
LINK_TEL_STOP = 38,
LINK_MUSIC_START = 39,
LINK_MUSIC_STOP = 40,
LINK_SCREEN_CONTROLLER = 62,
LINK_SCREEN_ACCESSORY = 63,
LINK_TAKE_AUDIO = 80,
LINK_UNTAKE_AUDIO = 81,
LINK_USE_USB0 = 82,
LINK_USE_USB1 = 83,
LINK_NO_ERROR = 0,
LINK_BTCONNECT_ERROR = -1000,
LINK_BTCOMM_ERROR = -1001,
LINK_BTAUTH_ERROR = -1002,
LINK_BTIDRECJECT_ERROR = -1003,
}Link_STATUS;
struct IAACallbacks
{
void (*video_init)(void* cb_ctx, int w, int h, int x, int y);
void (*video_uninit)(void* cb_ctx);
void (*video_play)(void* cb_ctx, char *buf, int len);
void (*audio_init_callback)(void* cb_ctx, int type, int sample, int ch, int bits);
void (*audio_uninit_callback)(void* cb_ctx, int type);
void (*audio_play)(void* cb_ctx, int type, char *buf, int len);
void (*mic_init_callback)(void* cb_ctx, int sample, int ch, int bits);
void (*mic_uninit_callback)(void* cb_ctx);
void (*mic_capture)(void* cb_ctx, char *buf, int len);
void (*bt_paring_request_callback)(void* cb_ctx, const char *phoneAddr, int pairingMethod);
void (*status_notify)(void* cb_ctx, int status_type);
int (*rf_read_transfer_cb)(void* cb_ctx, char *buf, int len);//@Deprecated
int (*rf_write_transfer_cb)(void* cb_ctx, char *buf, int len);
void (*json_msg_notify)(void* cb_ctx, char *buf, int len);
void* cb_ctx;
};
typedef struct __auto_cfg_info
{
short width;//pixel
short height;
short density;
short fps;
char* wifi_ssid;
char* wifi_passwd;
char wifi_channel;
bool disable_auto_audio;
bool video_auto_start;
} auto_cfg_info;
extern auto_cfg_info *g_auto_link_info;
int android_auto_init(struct IAACallbacks* cbs);
int android_auto_rfcomm_read_data_proc(char *buf, int len);
void android_auto_start();
void android_auto_set_rfcomm_info(const char * ssid, const char * passwd, const char * mac, int securityMode, const char * ip, int port);
void android_auto_set_BT_paring_status(bool paired, const char *pinCode, int status);
void android_auto_send_touch_event(unsigned int x, unsigned int y, int action);
void android_auto_send_mul_touch_event(int pointer_id, unsigned int pointer_x, unsigned int pointer_y, int event_type);
void android_auto_send_key_event(unsigned int keycode, int press);
void android_auto_send_knob_event(unsigned int keycode, int delta);
void android_auto_set_night_mode(bool night);
void android_auto_get_video_focus(int mode);
void android_auto_release_video_focus(int mode);
void android_auto_get_audio_focus(int mode);
void android_auto_release_audio_focus(int mode);
#endif

Binary file not shown.

View File

@ -0,0 +1,302 @@
#include <stdio.h>
#include <stdint.h>
#include "carlink_video.h"
#include "carlink_common.h"
#include "AndroidAuto.h"
#include "board.h"
#if CARLINK_AA
struct AAHandle
{
struct ICalinkEventCallbacks carlinkEventCB;
struct IAACallbacks carlinkAACB;
bool mInitDone;
bool mBTConnected;
bool mRfcommReady;
char mLocalBTMac[6];
char mRemoteBTMac[6];
char mIp[32];
};
//extern int debug_buf_ref;
struct AAHandle gAACtx;
static bool g_aa_disable = false;
static void android_auto_notify_event(struct carlink_event *ev, enum CARLINK_EVENT_TYPE type, bool disable_filter)
{
ev->link_type = CARLINK_AUTO_WIRELESS;
ev->disable_filter = disable_filter;
ev->type = type;
carlink_notify_event(ev);
}
static void start_aa(struct AAHandle* pctx)
{
if (!pctx->mInitDone)
return;
//if (pctx->mBTConnected)
// return;
if (!pctx->mRfcommReady)
return;
if (g_aa_disable)
return;
printf("%s:%d\r\n", __func__, __LINE__);
g_auto_link_info->wifi_ssid = (char *)carlink_get_wifi_ssid();
g_auto_link_info->wifi_passwd = (char *)carlink_get_wifi_passwd;
android_auto_set_rfcomm_info((const char*)carlink_get_wifi_ssid(),
(const char*)carlink_get_wifi_passwd(), (const char*)carlink_get_wifi_mac(), 5, (const char*)pctx->mIp, 0);
android_auto_start();
}
static void onEventAA(void* ctx, const struct carlink_event *ev)
{
enum CARLINK_EVENT_TYPE type;
struct AAHandle* pctx = (struct AAHandle*)ctx;
if (NULL == ev)
return;
if (ev->link_type != CARLINK_AUTO_WIRELESS && !ev->disable_filter)// skip not aa event
return;
type = ev->type;
switch (type) {
case -1: {
break;
}
case CARLINK_EVENT_INIT_DONE:
pctx->mInitDone = true;
start_aa(pctx);
break;
case CARLINK_EVENT_BT_CONNECT: {
pctx->mBTConnected = true;
start_aa(pctx);
break;
}
case CARLINK_EVENT_BT_AA_RFCOMM_READY: {
pctx->mRfcommReady = true;
start_aa(pctx);
break;
}
case CARLINK_EVENT_BT_DISCONNECT: {
pctx->mBTConnected = false;
pctx->mRfcommReady = false;
break;
}
case CARLINK_EVENT_WIFI_CONNECT: {
break;
}
case CARLINK_EVENT_MSG_SESSION_CONNECT: {
break;
}
case CARLINK_EVENT_MSG_SESSION_STOP: {
printf("%s:%d\r\n", __func__, __LINE__);
start_aa(pctx);
break;
}
default:
break;
}
}
static void aa_rfcomm_data_read(void* ctx, const void* buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)ctx;
if (!pctx->mRfcommReady)
return;
android_auto_rfcomm_read_data_proc((char*)buf, len);
}
static int rf_write_transfer_cb(void* cb_ctx, char *buf, int len)
{
int ret = -1;
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
if (!pctx->mRfcommReady)
return -1;
ret = carlink_auto_rfcomm_data_write(buf, len);
return ret;
}
static void video_init_impl(void* cb_ctx, int w, int h, int x, int y)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
printf("x:%d y:%d w:%d h:%d\r\n", x, y, w, h);
set_carlink_active_video_info(x, y);
h264_dec_ctx_init();
set_carlink_display_state(1);
//debug_buf_ref = 1;
}
static void video_uninit_impl(void* cb_ctx)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
set_carlink_display_state(0);
set_carlink_active_video_info(0, 0);
}
int g_v_count;
static void video_play_impl(void* cb_ctx, char *buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
video_frame_s* frame = NULL;
get_retry:
frame = get_h264_frame_buf();
if (NULL == frame) {
//printf("h264 frame is empty\r\n");
vTaskDelay(pdMS_TO_TICKS(10));
goto get_retry;
//continue;
}
memcpy(frame->cur, buf, len);
frame->len = len;
notify_h264_frame_ready(&frame);
if (g_v_count++ > 50) {
//android_auto_get_video_focus(0);
}
}
static void audio_init_callback_impl(void* cb_ctx, int type, int sample, int ch, int bits)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
}
static void audio_uninit_callback_impl(void* cb_ctx, int type)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
}
static void audio_play_impl(void* cb_ctx, int type, char *buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
}
static void mic_init_callback_impl(void* cb_ctx, int sample, int ch, int bits)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
}
static void mic_uninit_callback_impl(void* cb_ctx)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
}
static void mic_capture_impl(void* cb_ctx, char *buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
}
static void bt_paring_request_callback_impl(void* cb_ctx, const char *phoneAddr, int pairingMethod)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
}
static void status_notify_impl(void* cb_ctx, int status_type)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
struct carlink_event ev = {0};
if (status_type == LINK_REMOVED) {
printf("%s:%d\r\n", __func__, __LINE__);
android_auto_notify_event(&ev, CARLINK_EVENT_MSG_SESSION_STOP, 0);
}
}
static void json_msg_notify_impl(void* cb_ctx, char *buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
}
int carlink_aa_init()
{
int ret = -1;
struct AAHandle* pctx = &gAACtx;
struct IAACallbacks* carlinkAACBPtr = NULL;
memset((void*)pctx, 0, sizeof(struct AAHandle));
g_auto_link_info->width = CARLINK_VIDEO_WIDTH;
g_auto_link_info->height = CARLINK_VIDEO_HEIGHT;
g_auto_link_info->fps = 30;
g_auto_link_info->density = 160;
g_auto_link_info->disable_auto_audio = 1;
g_auto_link_info->video_auto_start = 1;
set_carlink_display_info(0, 0, CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT);
set_carlink_video_info(CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT, 30);
ret = carlink_common_init();
pctx->carlinkEventCB.onEvent = onEventAA;
pctx->carlinkEventCB.rfcomm_data_read = aa_rfcomm_data_read;
pctx->carlinkEventCB.cb_ctx = (void*)pctx;
carlink_register_event_callbacks(&pctx->carlinkEventCB);
ret = carlink_bt_wifi_init();
carlinkAACBPtr = &pctx->carlinkAACB;
carlinkAACBPtr->video_init = video_init_impl;
carlinkAACBPtr->video_uninit = video_uninit_impl;
carlinkAACBPtr->video_play = video_play_impl;
carlinkAACBPtr->audio_init_callback = audio_init_callback_impl;
carlinkAACBPtr->audio_uninit_callback = audio_uninit_callback_impl;
carlinkAACBPtr->mic_init_callback = mic_init_callback_impl;
carlinkAACBPtr->mic_uninit_callback = mic_uninit_callback_impl;
carlinkAACBPtr->mic_capture = mic_capture_impl;
carlinkAACBPtr->bt_paring_request_callback = bt_paring_request_callback_impl;
carlinkAACBPtr->status_notify = status_notify_impl;
carlinkAACBPtr->json_msg_notify = json_msg_notify_impl;
carlinkAACBPtr->rf_read_transfer_cb = NULL;
carlinkAACBPtr->rf_write_transfer_cb = rf_write_transfer_cb;
carlinkAACBPtr->cb_ctx = (void*)pctx;
ret = android_auto_init(&pctx->carlinkAACB);
{
char ip[4] = {0};
carlink_get_ap_ip_addr(ip);
sprintf(pctx->mIp, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
}
{
struct carlink_event ev = {0};
android_auto_notify_event(&ev, CARLINK_EVENT_INIT_DONE, 0);
}
return 0;
}
void carlink_aa_enable(int enable)
{
if (enable) {
g_aa_disable = false;
} else {
g_aa_disable = true;
}
}
#else
int carlink_aa_init()
{
return 0;
}
void carlink_aa_enable(int enable)
{
(void)enable;
}
#endif

View File

@ -0,0 +1,369 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "carlink_video.h"
#include "carlink_common.h"
#include "AndroidAuto.h"
#include "board.h"
#include "task.h"
#if CARLINK_AA
struct AAHandle
{
struct ICalinkEventCallbacks carlinkEventCB;
struct IAACallbacks carlinkAACB;
bool mInitDone;
bool mBTConnected;
bool mRfcommReady;
char mLocalBTMac[6];
char mRemoteBTMac[6];
char mIp[32];
bool mAAConnected;
};
//extern int debug_buf_ref;
struct AAHandle gAACtx;
static bool g_aa_disable = false;
static void android_auto_notify_event(struct carlink_event *ev, enum CARLINK_EVENT_TYPE type, bool disable_filter)
{
ev->link_type = CARLINK_AUTO_WIRELESS;
ev->disable_filter = disable_filter;
ev->type = type;
carlink_notify_event(ev);
}
static void start_aa(struct AAHandle* pctx)
{
if (!pctx->mInitDone)
return;
//if (pctx->mBTConnected)
// return;
if (!pctx->mRfcommReady)
return;
if (g_aa_disable)
return;
printf("%s:%d\r\n", __func__, __LINE__);
g_auto_link_info->wifi_ssid = (char *)carlink_get_wifi_ssid();
g_auto_link_info->wifi_passwd = (char *)carlink_get_wifi_passwd;
android_auto_set_rfcomm_info((const char*)carlink_get_wifi_ssid(),
(const char*)carlink_get_wifi_passwd(), (const char*)carlink_get_wifi_mac(), 5, (const char*)pctx->mIp, 0);
android_auto_start();
}
static void carlink_aa_input_event_proc(const struct carlink_event *ev)
{
uint8_t key = ev->u.para[0];
bool pressed = (bool)ev->u.para[1];
if (key == 19) {//right
android_auto_send_knob_event(65536, 1);
} else if (key == 20) {
android_auto_send_knob_event(65536, -1);
} else {
if (pressed)
android_auto_send_key_event(3, 1);
else
android_auto_send_key_event(3, 0);
}
}
static void onEventAA(void* ctx, const struct carlink_event *ev)
{
enum CARLINK_EVENT_TYPE type;
struct AAHandle* pctx = (struct AAHandle*)ctx;
if (NULL == ev)
return;
if (ev->link_type != CARLINK_AUTO_WIRELESS && !ev->disable_filter)// skip not aa event
return;
type = ev->type;
switch (type) {
case CARLINK_EVENT_KEY_EVENT:
if (!pctx->mAAConnected)
break;
carlink_aa_input_event_proc(ev);
break;
case -1: {
break;
}
case CARLINK_EVENT_INIT_DONE:
pctx->mInitDone = true;
start_aa(pctx);
break;
case CARLINK_EVENT_BT_CONNECT: {
pctx->mBTConnected = true;
start_aa(pctx);
break;
}
case CARLINK_EVENT_BT_AA_RFCOMM_READY: {
pctx->mRfcommReady = true;
start_aa(pctx);
break;
}
case CARLINK_EVENT_BT_DISCONNECT: {
pctx->mBTConnected = false;
pctx->mRfcommReady = false;
break;
}
case CARLINK_EVENT_WIFI_CONNECT: {
break;
}
case CARLINK_EVENT_MSG_SESSION_CONNECT: {
break;
}
case CARLINK_EVENT_MSG_SESSION_STOP: {
printf("%s:%d\r\n", __func__, __LINE__);
start_aa(pctx);
break;
}
default:
break;
}
}
static void aa_rfcomm_data_read(void* ctx, const void* buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)ctx;
if (!pctx->mRfcommReady)
return;
android_auto_rfcomm_read_data_proc((char*)buf, len);
}
static int rf_write_transfer_cb(void* cb_ctx, char *buf, int len)
{
int ret = -1;
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
if (!pctx->mRfcommReady)
return -1;
ret = carlink_auto_rfcomm_data_write((unsigned char *)buf, len);
return ret;
}
int g_v_count;
static void video_init_impl(void* cb_ctx, int w, int h, int x, int y)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
printf("x:%d y:%d w:%d h:%d\r\n", x, y, w, h);
set_carlink_active_video_info(x, y);
h264_dec_ctx_init();
set_carlink_display_state(1);
//carlink_bt_close();
g_v_count = 0;
//debug_buf_ref = 1;
}
static void video_uninit_impl(void* cb_ctx)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
printf("%s:%d\r\n", __func__, __LINE__);
set_carlink_display_state(0);
set_carlink_active_video_info(0, 0);
}
static void video_play_impl(void* cb_ctx, char *buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
video_frame_s* frame = NULL;
(void)pctx;
get_retry:
frame = get_h264_frame_buf();
if (NULL == frame) {
//printf("h264 frame is empty\r\n");
vTaskDelay(pdMS_TO_TICKS(10));
goto get_retry;
//continue;
}
memcpy(frame->cur, buf, len);
frame->len = len;
notify_h264_frame_ready(&frame);
if (g_v_count++ > 50) {//enable_malloc_debug = 1;
//android_auto_get_video_focus(0);
}
}
static void audio_init_callback_impl(void* cb_ctx, int type, int sample, int ch, int bits)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
}
static void audio_uninit_callback_impl(void* cb_ctx, int type)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
}
static void audio_play_impl(void* cb_ctx, int type, char *buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
}
static void mic_init_callback_impl(void* cb_ctx, int sample, int ch, int bits)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
}
static void mic_uninit_callback_impl(void* cb_ctx)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
}
static void mic_capture_impl(void* cb_ctx, char *buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
}
static void bt_paring_request_callback_impl(void* cb_ctx, const char *phoneAddr, int pairingMethod)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
}
static void status_notify_impl(void* cb_ctx, int status_type)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
struct carlink_event ev = {0};
if (status_type == LINK_REMOVED) {
printf("%s:%d\r\n", __func__, __LINE__);
android_auto_notify_event(&ev, CARLINK_EVENT_MSG_SESSION_STOP, 0);
} else if (status_type == LINK_SUCCESS) {
pctx->mAAConnected = true;
}
}
static void json_msg_notify_impl(void* cb_ctx, char *buf, int len)
{
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
(void)pctx;
}
int _carlink_aa_init()
{
int ret = -1;
struct AAHandle* pctx = &gAACtx;
struct IAACallbacks* carlinkAACBPtr = NULL;
memset((void*)pctx, 0, sizeof(struct AAHandle));
g_auto_link_info->width = CARLINK_VIDEO_WIDTH;
g_auto_link_info->height = CARLINK_VIDEO_HEIGHT;
g_auto_link_info->fps = 30;
g_auto_link_info->density = 160;
g_auto_link_info->disable_auto_audio = 1;
g_auto_link_info->video_auto_start = 1;
set_carlink_display_info(0, 0, CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT);
set_carlink_video_info(CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT, 30);
ret = carlink_common_init();
pctx->carlinkEventCB.onEvent = onEventAA;
pctx->carlinkEventCB.rfcomm_data_read = aa_rfcomm_data_read;
pctx->carlinkEventCB.cb_ctx = (void*)pctx;
carlink_register_event_callbacks(&pctx->carlinkEventCB);
ret = carlink_bt_wifi_init();
carlinkAACBPtr = &pctx->carlinkAACB;
carlinkAACBPtr->video_init = video_init_impl;
carlinkAACBPtr->video_uninit = video_uninit_impl;
carlinkAACBPtr->video_play = video_play_impl;
carlinkAACBPtr->audio_init_callback = audio_init_callback_impl;
carlinkAACBPtr->audio_uninit_callback = audio_uninit_callback_impl;
carlinkAACBPtr->audio_play = audio_play_impl;
carlinkAACBPtr->mic_init_callback = mic_init_callback_impl;
carlinkAACBPtr->mic_uninit_callback = mic_uninit_callback_impl;
carlinkAACBPtr->mic_capture = mic_capture_impl;
carlinkAACBPtr->bt_paring_request_callback = bt_paring_request_callback_impl;
carlinkAACBPtr->status_notify = status_notify_impl;
carlinkAACBPtr->json_msg_notify = json_msg_notify_impl;
carlinkAACBPtr->rf_read_transfer_cb = NULL;
carlinkAACBPtr->rf_write_transfer_cb = rf_write_transfer_cb;
carlinkAACBPtr->cb_ctx = (void*)pctx;
ret = android_auto_init(&pctx->carlinkAACB);
{
char ip[4] = {0};
carlink_get_ap_ip_addr(ip);
sprintf(pctx->mIp, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
}
{
struct carlink_event ev = {0};
android_auto_notify_event(&ev, CARLINK_EVENT_INIT_DONE, 0);
}
return ret;
}
static void taskInitCarlinkAA(void* param)
{
_carlink_aa_init();
vTaskDelete(NULL);
}
int carlink_aa_init()
{
xTaskCreate(taskInitCarlinkAA, "initThread", 2048 * 4, NULL, 1, NULL);
return 0;
}
void carlink_aa_enable(int enable)
{
if (enable) {
g_aa_disable = false;
} else {
g_aa_disable = true;
}
}
#else
int carlink_aa_init()
{
return 0;
}
void carlink_aa_enable(int enable)
{
(void)enable;
}
#endif

View File

@ -0,0 +1,7 @@
#ifndef _CARLINK_AA_H_
#define _CARLINK_AA_H_
int carlink_aa_init();
void carlink_aa_enable(int enable);
#endif