A59项目初版工程 1.电压+光感adc采样优化 2.串口逻辑优化
96
app/carlink/AA/include/AndroidAuto.h
Normal file
@ -0,0 +1,96 @@
|
||||
#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;
|
||||
};
|
||||
|
||||
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);
|
||||
#endif
|
BIN
app/carlink/AA/lib/AndroidAuto.a
Normal file
264
app/carlink/AA/src/carlink_aa.c
Normal file
@ -0,0 +1,264 @@
|
||||
#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];
|
||||
|
||||
};
|
||||
|
||||
struct AAHandle gAACtx;
|
||||
|
||||
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;
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
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;
|
||||
|
||||
h264_dec_ctx_init();
|
||||
set_carlink_display_state(1);
|
||||
}
|
||||
|
||||
static void video_uninit_impl(void* cb_ctx)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
set_carlink_display_state(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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
#else
|
||||
int carlink_aa_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
25
app/carlink/CP/include/audio_callbacks.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef _AUDIO_CALLBACKS_H
|
||||
#define _AUDIO_CALLBACKS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int (*audio_start_callback_f)(void *ctx, int handle, int type, int rate, int bits, int channels);
|
||||
typedef void (*audio_stop_callback_f)(void *ctx, int handle, int type);
|
||||
typedef void ( *audio_reset_DSP_mode_callback_f)(void *ctx, int mode);
|
||||
|
||||
typedef struct audio_callbacks
|
||||
{
|
||||
audio_start_callback_f audio_start_callback;
|
||||
audio_stop_callback_f audio_stop_callback;
|
||||
audio_reset_DSP_mode_callback_f audio_reset_DSP_mode_callback;
|
||||
void *ctx;
|
||||
}audio_callbacks_t;
|
||||
|
||||
void audio_register_callbacks(void *cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
272
app/carlink/CP/include/carplay.h
Normal file
@ -0,0 +1,272 @@
|
||||
#ifndef __CARPLAY_IF_H_H
|
||||
#define __CARPLAY_IF_H_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*#ifndef CAPLAY_LINK_TYPE
|
||||
#define CAPLAY_LINK_TYPE
|
||||
typedef enum
|
||||
{
|
||||
CARPLAY = 0x00,
|
||||
CARLIFE,
|
||||
ANDROID_CARLIFE,
|
||||
ANDROID_MIRROR = 3,
|
||||
IOS_CARLIFE,
|
||||
ANDROID_AUTO = 5,
|
||||
ECLINK = 0x06,
|
||||
CARPLAY_WIRELESS
|
||||
}Link_TYPE;
|
||||
#endif*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CALL_ACCEPT = 2,
|
||||
CALL_DROP = 3,
|
||||
}CALL;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEDIA_NONE = 0,
|
||||
MEDIA_PLAY,
|
||||
MEDIA_PAUSE,
|
||||
MEDIA_PLAY_PAUSE,
|
||||
MEDIA_NEXT,
|
||||
MEDIA_PREVIOUS
|
||||
}MEDIA;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_MEDIA = 0,
|
||||
AUDIO_TELEPHONE,
|
||||
AUDIO_RECOGNITION,
|
||||
AUDIO_ALERT,
|
||||
AUDIO_REC,
|
||||
AUDIO_ALT,
|
||||
AUDIO_AUX_IN,
|
||||
AUDIO_AUX_OUT
|
||||
} AUDIO_TYPE;
|
||||
|
||||
/*
|
||||
|
||||
typedef enum _IAP2_LINK_STATUS
|
||||
{
|
||||
IAP2_INIT = -1,
|
||||
IAP2_USB_HOST_INSERTED,
|
||||
IAP2_USB_HOST_REMOVE,
|
||||
IAP2_USB_SWITCH_FAIL,
|
||||
IAP2_CONNECT,
|
||||
IAP2_DISCONNECT,
|
||||
}IAP2_LINK_STATUS;*/
|
||||
|
||||
#ifndef AirplayModeStateAlias
|
||||
#define AirplayModeStateAlias
|
||||
|
||||
typedef int CarplayEntity;
|
||||
#define CarplayEntity_NotApplicable 0
|
||||
#define CarplayEntity_Controller 1
|
||||
#define CarplayEntity_Accessory 2
|
||||
|
||||
typedef int CarplayTransferType;
|
||||
#define CarplayTransferType_NotApplicable 0
|
||||
#define CarplayTransferType_Take 1 // Transfer ownership permanently.
|
||||
#define CarplayTransferType_Untake 2 // Release permanent ownership.
|
||||
#define CarplayTransferType_Borrow 3 // Transfer ownership temporarily.
|
||||
#define CarplayTransferType_Unborrow 4 // Release temporary ownership.
|
||||
|
||||
|
||||
typedef int CarplayTransferPriority;
|
||||
#define CarplayTransferPriority_NotApplicable 0
|
||||
#define CarplayTransferPriority_NiceToHave 100 // Transfer succeeds only if constraint is <= Anytime.
|
||||
#define CarplayTransferPriority_UserInitiated 500 // Transfer succeeds only if constraint is <= UserInitiated.
|
||||
|
||||
|
||||
typedef int CarplayConstraint;
|
||||
#define CarplayConstraint_NotApplicable 0
|
||||
#define CarplayConstraint_Anytime 100 // Resource may be taken/borrowed at any time.
|
||||
#define CarplayConstraint_UserInitiated 500 // Resource may be taken/borrowed if user initiated.
|
||||
#define CarplayConstraint_Never 1000 // Resource may never be taken/borrowed.
|
||||
|
||||
|
||||
typedef int CarplayTriState;
|
||||
#define CarplayTriState_NotApplicable 0
|
||||
#define CarplayTriState_False -1
|
||||
#define CarplayTriState_True 1
|
||||
|
||||
|
||||
typedef int CarplaySpeechMode;
|
||||
#define CarplaySpeechMode_NotApplicable 0
|
||||
#define CarplaySpeechMode_None -1 // No speech-related states are active.
|
||||
#define CarplaySpeechMode_Speaking 1 // Device is speaking to the user.
|
||||
#define CarplaySpeechMode_Recognizing 2 // Device is recording audio to recognize speech from the user.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CarplayEntity entity;
|
||||
CarplaySpeechMode mode;
|
||||
|
||||
}CarPlaySpeechState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CarplayEntity screen; // Owner of the screen.
|
||||
CarplayEntity permScreen; // Permanent owner of screen.
|
||||
CarplayEntity mainAudio; // Owner of main audio.
|
||||
CarplayEntity permMainAudio; // Permanent owner of main audio.
|
||||
CarplayEntity phoneCall; // Owner of phone call.
|
||||
CarPlaySpeechState speech; // Owner of speech and its mode.
|
||||
CarplayEntity turnByTurn; // Owner of navigation.
|
||||
|
||||
} CarPlayModeState;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef void ( *CarplaySessionStarted_f )(void *ctx);
|
||||
typedef void ( *CarplaySessionStop_f )(void *ctx);
|
||||
typedef void ( *CarplaySessionModesChanged_f )(void *ctx, const CarPlayModeState * inState);
|
||||
typedef void ( *CarplaySessionRequestUI_f )(void *ctx);
|
||||
typedef void ( *CarplaySessionDuckAudio_f)(void *ctx, double inDurationSecs, double inVolume);
|
||||
typedef void ( *CarplaySessionUnduckAudio_f)(void *ctx, double inDurationSecs);
|
||||
typedef void ( *CarplayDisableBtSession_f)(void *ctx);
|
||||
typedef void ( *CarplayNotifyDeviceName_f)(void *ctx, const char *name, int len);
|
||||
typedef void ( *CarplayBonjourServiceFound_f)(void *ctx, char phone_bt_mac[6]);
|
||||
typedef void ( *CarplayViewAreaUpdateNotify_f)(void *ctx, int index);
|
||||
//typedef void ( *CarplayMsgNotify_f)(void *ctx, int id, int para1, int para2, const char* msg, int msgLen);
|
||||
typedef void ( *CarplayMsgNotify_f)(void *ctx, const char* msg, int msgLen);
|
||||
|
||||
typedef struct carplay_session_callbacks
|
||||
{
|
||||
CarplaySessionStarted_f SessionStarted;
|
||||
CarplaySessionStop_f SessionStop;
|
||||
CarplaySessionModesChanged_f SessionModesChanged;
|
||||
CarplaySessionRequestUI_f SessionRequestUI;
|
||||
CarplaySessionDuckAudio_f SessionDuckAudio;
|
||||
CarplaySessionUnduckAudio_f SessionUnduckAudio;
|
||||
CarplayDisableBtSession_f DisableBtSession;
|
||||
CarplayNotifyDeviceName_f NotifyDeviceName;
|
||||
CarplayBonjourServiceFound_f BonjourServiceFound;
|
||||
CarplayViewAreaUpdateNotify_f ViewAreaUpdateNotify;
|
||||
|
||||
CarplayMsgNotify_f MsgNotify;
|
||||
void *ctx;
|
||||
}carplay_session_callbacks_t;
|
||||
|
||||
typedef carplay_session_callbacks_t carplaySessionCbs;
|
||||
|
||||
/*
|
||||
* @brief 初始化carplay的基本信息,整个程序的生命周期里面调用一次;
|
||||
*/
|
||||
int carplay_init();
|
||||
void carplay_uninit();
|
||||
/*
|
||||
* @brief 注册carplay plugin的回调函数;
|
||||
* @param cbs指向carplay_session_callbacks_t类型的变量;
|
||||
*/
|
||||
void carplay_register_callbacks(void *cbs);
|
||||
/*
|
||||
* @brief 启动carplay;
|
||||
*/
|
||||
int carplay_start();
|
||||
|
||||
void start_carplay_client_connect();
|
||||
/*
|
||||
* @brief 停止carplay;
|
||||
*/
|
||||
void carplay_stop();
|
||||
/*
|
||||
* @brief 设置要连接手机的蓝牙mac地址,无线连接的时候使用;
|
||||
* @param bt_addr 蓝牙mac地址;
|
||||
*/
|
||||
void carplay_wl_set_iphone_mac_addr(char bt_addr[6]);
|
||||
|
||||
/*
|
||||
* @brief 发送电话按键给苹果;
|
||||
* @param button 类型见enum CALL;
|
||||
*/
|
||||
void Telephone_button_Update(unsigned button);
|
||||
/*
|
||||
* @brief 发送多媒体按键给苹果;
|
||||
* @param button 类型见enum MEDIA;
|
||||
*/
|
||||
void Media_button_Update(unsigned button);
|
||||
/*
|
||||
* @brief 发送siri按键给苹果;
|
||||
* @param button 1表示按下启动siri,0表示释放来结束siri;
|
||||
*/
|
||||
void send_siri_cmd(int button);
|
||||
void send_single_touchscreen_x_y_2_carplay(unsigned short x, unsigned short y, unsigned char pressed);
|
||||
void send_mul_touchscreen_x_y_2_carplay(
|
||||
unsigned char finger_idx1, unsigned char pressed1,
|
||||
unsigned short x1, unsigned short y1,
|
||||
unsigned char finger_idx2, unsigned char pressed2,
|
||||
unsigned short x2, unsigned short y2
|
||||
);
|
||||
/*
|
||||
* @brief 发送旋钮信息给苹果;
|
||||
*/
|
||||
void KnobUpdate(char gSelectButtonPressed,
|
||||
char gHomeButtonPressed,
|
||||
char gBackButtonPressed,
|
||||
double gXPosition,
|
||||
double gYPosition,
|
||||
char gWheelPositionRelative
|
||||
);
|
||||
|
||||
/*
|
||||
* @brief 请求iphone启动一个应用;
|
||||
* @param bundleId app的包名;
|
||||
* @param alert app启动的时候时候弹出警告对话框;
|
||||
*/
|
||||
int apple_app_launcher(char * bundleId, char alert);
|
||||
|
||||
/*
|
||||
* @brief 要求iphone发送关键帧;
|
||||
*/
|
||||
void force_key_frame();
|
||||
/*
|
||||
* @brief 设置夜间模式;
|
||||
* @param inNightMode 1表示进入夜间模式,0表示退出夜间模式
|
||||
*/
|
||||
void set_night_mode(char inNightMode);
|
||||
|
||||
/*
|
||||
* @brief 请求苹果手机输出视频数据;
|
||||
*/
|
||||
void request_UI(char *url);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void borrow_screen(int priority, int unborrow_constraint);
|
||||
void unborrow_screen(void);
|
||||
void take_screen(int priority, int take_constraint, int borrow_constraint);
|
||||
void untake_screen(void);
|
||||
void borrow_audio(int priority, int unborrow_constraint);
|
||||
void unborrow_audio(void);
|
||||
void take_audio(int priority, int take_constraint, int borrow_constraint);
|
||||
void untake_audio(void);
|
||||
void carplay_send_change_modes(CarplayTransferType inScreenType,
|
||||
CarplayTransferPriority inScreenPriority,
|
||||
CarplayConstraint inScreenTake,
|
||||
CarplayConstraint inScreenBorrow,
|
||||
CarplayTransferType inAudioType,
|
||||
CarplayTransferPriority inAudioPriority,
|
||||
CarplayConstraint inAudioTake,
|
||||
CarplayConstraint inAudioBorrow,
|
||||
CarplayTriState inPhone,
|
||||
CarplaySpeechMode inSpeech,
|
||||
CarplayTriState inTurnByTurn);
|
||||
|
||||
int carplay_ipc_start();
|
||||
void carplay_ipc_stop();
|
||||
void process_play_stream(int handle, void *buffer, int len, int frames, unsigned long long timestamp);
|
||||
void process_record_stream(int handle, void *buffer, int len, int frames, unsigned long long timestamp);
|
||||
|
||||
int carplay_get_iphone_ip_addr(char *ipaddr);
|
||||
void carplay_wl_set_iphone_mac_addr(char bt_addr[6]);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
80
app/carlink/CP/include/iap.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef __IAP_H_H
|
||||
#define __IAP_H_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum _IAP2_LINK_STATUS
|
||||
{
|
||||
IAP2_INIT = -1,
|
||||
IAP2_USB_HOST_INSERTED,
|
||||
IAP2_CONNECT,
|
||||
IAP2_ID_OK,
|
||||
IAP2_USB_HOST_REMOVE,
|
||||
IAP2_USB_SWITCH_FAIL,
|
||||
IAP2_ID_FAIL,
|
||||
IAP2_DISCONNECT
|
||||
}IAP2_LINK_STATUS;
|
||||
|
||||
typedef void (*iap2_link_status_cb_f)(void *ctx, IAP2_LINK_STATUS status);
|
||||
typedef void (*iap2_msg_time_update_cb_f)(void *ctx, long long time, int zone_offset);
|
||||
typedef void (*iap2_msg_time_zone_update_cb_f)(void *ctx, long long time, int16_t zone, int8_t daylightOff);
|
||||
typedef void (*iap2_msg_gps_cb_f)(void *ctx, unsigned char session, int start);
|
||||
typedef void (*iap2_msg_gps_gprmc_data_status_cb_f)(void *ctx, int value_a, int value_v, int value_x);
|
||||
typedef void (*iap2_msg_identify_cb_f)(void *ctx, int type, int ok);
|
||||
typedef void (*iap2_msg_wl_carplay_update_cb_f)(void *ctx, int status);
|
||||
typedef int (*iap2_usb_switch_cb_f)(void *ctx, int state);
|
||||
typedef int (*iap2_write_data_cb_f)(void *ctx, char *buf, int len);
|
||||
typedef void (*iap2_msg_language_update_cb_f)(void *ctx, const char *lang);
|
||||
typedef void (*iap2_msg_call_state_update_cb_f)(void *ctx,
|
||||
const char *remoteId,
|
||||
const char *displayName,
|
||||
int status,
|
||||
int direction,
|
||||
const char *uuid,
|
||||
const char *addrBookId,
|
||||
const char *label,
|
||||
int service);
|
||||
|
||||
typedef void (*iap2_msg_nowplaying_update_cb_f)(void *ctx,
|
||||
int playback_status, int elapsed_time,
|
||||
uint8_t* media_item_title, int media_item_title_len,
|
||||
uint8_t* media_item_album_title, int media_item_album_title_len,
|
||||
uint8_t* media_item_artist, int media_item_artist_len,
|
||||
int song_length_ms);
|
||||
|
||||
typedef void (*iap2_msg_msg_json_cb_f)(void *ctx, const char* buf, int len);
|
||||
typedef struct iap2_callbacks_st
|
||||
{
|
||||
iap2_link_status_cb_f iap2_link_status_cb;
|
||||
iap2_msg_time_update_cb_f iap2_msg_time_update_cb;
|
||||
iap2_msg_gps_cb_f iap2_msg_gps_cb;
|
||||
iap2_msg_gps_gprmc_data_status_cb_f iap2_msg_gps_gprmc_data_status_cb;
|
||||
iap2_msg_identify_cb_f iap2_msg_identify_cb;
|
||||
iap2_msg_wl_carplay_update_cb_f iap2_msg_wl_carplay_update_cb;
|
||||
iap2_msg_language_update_cb_f iap2_msg_language_update_cb;
|
||||
iap2_msg_call_state_update_cb_f iap2_msg_call_state_update_cb;
|
||||
iap2_usb_switch_cb_f iap2_usb_switch_cb;
|
||||
iap2_write_data_cb_f iap2_write_data_cb;
|
||||
iap2_msg_time_zone_update_cb_f iap2_msg_time_zone_update_cb;
|
||||
iap2_msg_nowplaying_update_cb_f iap2_msg_nowplaying_update_cb;
|
||||
iap2_msg_msg_json_cb_f iap2_msg_msg_json_cb;
|
||||
|
||||
void *ctx;
|
||||
}iap2_callbacks;
|
||||
|
||||
void iap2_register_callbacks(iap2_callbacks *pcb);
|
||||
int iap2_start();
|
||||
int iap2_start_wifi_session();
|
||||
int force_iap2_bt_start();
|
||||
void iap2_stop();
|
||||
int apple_send_pascd(unsigned char session, char *data);
|
||||
int iap2_read_data_proc(char *buf, int len);
|
||||
int apple_start_update_call_state(int start);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
26
app/carlink/CP/include/video_callbacks.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef _VIDEO_CALLBACKS_H
|
||||
#define _VIDEO_CALLBACKS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef int (*video_start_callback_f)(void *ctx);
|
||||
typedef void (*video_stop_callback_f)(void *ctx);
|
||||
typedef int (*video_proc_data_callback_f)(void *ctx, char *buf, int len);
|
||||
|
||||
typedef struct video_callbacks
|
||||
{
|
||||
video_start_callback_f video_start_callback;
|
||||
video_stop_callback_f video_stop_callback;
|
||||
video_proc_data_callback_f video_proc_data_callback;
|
||||
void *ctx;
|
||||
}video_callbacks_t;
|
||||
|
||||
void video_register_callbacks(void *cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
BIN
app/carlink/CP/lib/carplay.a
Normal file
446
app/carlink/CP/src/carlink_cp.c
Normal file
@ -0,0 +1,446 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include "iap.h"
|
||||
#include "carplay.h"
|
||||
#include "audio_callbacks.h"
|
||||
#include "video_callbacks.h"
|
||||
#include "carlink_cp.h"
|
||||
//#include "DispatchLite.h"
|
||||
#include "mycommon.h"
|
||||
#include "ff_sfdisk.h"
|
||||
#include "carlink_video.h"
|
||||
#include "carlink_cp_priv.h"
|
||||
|
||||
#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include "carlink_common.h"
|
||||
#include "board.h"
|
||||
|
||||
#if CARLINK_CP
|
||||
|
||||
struct carplay_ctx
|
||||
{
|
||||
struct ICalinkEventCallbacks carlinkEventCB;
|
||||
|
||||
bool mInitDone;
|
||||
bool mBTConnected;
|
||||
bool mIapReady;
|
||||
bool mCarplayConnected;
|
||||
char mLocalBTMac[6];
|
||||
char mRemoteBTMac[6];
|
||||
char mIp[32];
|
||||
};
|
||||
|
||||
struct carplay_ctx g_cp_handle;
|
||||
|
||||
static void carplay_init_parameter();
|
||||
void start_mdnsd();
|
||||
void start_mdnsd_posix();
|
||||
void stop_mdnsd_posix();
|
||||
|
||||
static void carplay_notify_event(struct carlink_event *ev, enum CARLINK_EVENT_TYPE type, bool disable_filter)
|
||||
{
|
||||
ev->link_type = CARLINK_CARPLAY_WIRELESS;
|
||||
ev->disable_filter = disable_filter;
|
||||
ev->type = type;
|
||||
carlink_notify_event(ev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void iap2_link_status(void *ctx, IAP2_LINK_STATUS status){}
|
||||
static int iap2_write_data(void *ctx, char *buf, int len)
|
||||
{
|
||||
(void)ctx;
|
||||
return carlink_iap_data_write((unsigned char *)buf, len);
|
||||
}
|
||||
static void iap2_msg_time_update(void *ctx, long long time, int zone_offset){}
|
||||
static void iap2_msg_gps(void *ctx, unsigned char session, int start){}
|
||||
static void iap2_msg_gps_gprmc_data_status(void *ctx, int value_a, int value_v, int value_x){}
|
||||
static void iap2_msg_identify(void *ctx, int type, int ok)
|
||||
{
|
||||
if (ok && !g_link_info->enable_iap_carplay_sess) {
|
||||
start_mdnsd_posix();
|
||||
}
|
||||
}
|
||||
static void iap2_msg_wl_carplay_update(void *ctx, int status){}
|
||||
//static void iap2_msg_language_update(void *ctx, const char *lang){}
|
||||
|
||||
static void carplay_session_started(void *ctx)
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
carplay_notify_event(&ev, CARLINK_EVENT_MSG_SESSION_CONNECT, 0);
|
||||
}
|
||||
|
||||
static void carplay_session_Stop(void *ctx)
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
carplay_notify_event(&ev, CARLINK_EVENT_MSG_SESSION_STOP, 0);
|
||||
}
|
||||
|
||||
static void carplay_session_modes_changed(void *ctx, const CarPlayModeState * inState){}
|
||||
static void carplay_session_requestUI(void *ctx){}
|
||||
static void carplay_session_duck_audio(void *ctx, double inDurationSecs, double inVolume){}
|
||||
static void carplay_session_unduck_audio(void *ctx, double inDurationSecs){}
|
||||
//static void carplay_session_notify_device_name(void *ctx, const char *name, int len){}
|
||||
|
||||
static void carplay_disable_bt_session(void *ctx)
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
|
||||
(void)ctx;
|
||||
|
||||
if (g_link_info->disable_carplay_audio)
|
||||
return;
|
||||
carplay_notify_event(&ev, CARLINK_EVENT_MSG_DISABLE_BT, 0);
|
||||
}
|
||||
|
||||
static int audio_start_callback_impl(void *ctx, int handle, int type, int rate, int bits, int channels)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
ret = carlink_cp_audio_start(handle, type, rate, bits, channels);
|
||||
return ret;
|
||||
}
|
||||
static void audio_stop_callback_impl(void *ctx, int handle, int type)
|
||||
{
|
||||
carlink_cp_audio_stop(handle, type);
|
||||
}
|
||||
extern char key_value;
|
||||
|
||||
static int video_start_callback_impl(void *ctx)
|
||||
{
|
||||
h264_dec_ctx_init();
|
||||
set_carlink_display_state(1);
|
||||
key_value = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void video_stop_callback_impl(void *ctx)
|
||||
{
|
||||
key_value = 0;
|
||||
set_carlink_display_state(0);
|
||||
}
|
||||
static int video_proc_data_callback_impl(void *ctx, char *buf, int len)
|
||||
{
|
||||
video_frame_s* frame = NULL;
|
||||
printf("video_proc_data len:%d\r\n", len);
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
static void carplay_viewArea_update_notify(void *ctx, int index){}
|
||||
static void resetDspMode(void *ctx, int mode){}
|
||||
static void carplay_msg_notify(void*ctx, const char* buf, int len){}
|
||||
|
||||
void test_carplay_modules();
|
||||
|
||||
static void start_cp(struct carplay_ctx* pctx)
|
||||
{
|
||||
if (!pctx->mInitDone)
|
||||
return;
|
||||
//if (pctx->mBTConnected)
|
||||
// return;
|
||||
if (!pctx->mIapReady)
|
||||
return;
|
||||
|
||||
if (pctx->mCarplayConnected)
|
||||
return;
|
||||
|
||||
g_link_info->enable_iap_carplay_sess = 1;
|
||||
g_link_info->is_old_carplay_ver = 0;
|
||||
g_link_info->wifi_passwd = (char *)carlink_get_wifi_passwd();
|
||||
g_link_info->wifi_ssid = (char *)carlink_get_wifi_ssid();
|
||||
g_link_info->wifi_channel = 36;
|
||||
|
||||
{
|
||||
char ip[4] = {0};
|
||||
carlink_get_ap_ip_addr(ip);
|
||||
g_link_info->ip_v4_addr[0] = ip[0];
|
||||
g_link_info->ip_v4_addr[1] = ip[1];
|
||||
g_link_info->ip_v4_addr[2] = ip[2];
|
||||
g_link_info->ip_v4_addr[3] = ip[3];
|
||||
}
|
||||
|
||||
carplay_start();
|
||||
}
|
||||
|
||||
|
||||
static void onEventCarplay(void* ctx, const struct carlink_event *ev)
|
||||
{
|
||||
enum CARLINK_EVENT_TYPE type;
|
||||
struct carplay_ctx* pctx = (struct carplay_ctx*)ctx;
|
||||
|
||||
if (NULL == ev)
|
||||
return;
|
||||
if (ev->link_type != CARLINK_CARPLAY_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_cp(pctx);
|
||||
break;
|
||||
case CARLINK_EVENT_BT_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_IAP_READY: {
|
||||
pctx->mIapReady = true;
|
||||
start_cp(pctx);
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_DISCONNECT: {
|
||||
pctx->mIapReady = false;
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_WIFI_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_CONNECT: {
|
||||
pctx->mCarplayConnected = 1;
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_STOP: {
|
||||
if (0 == pctx->mCarplayConnected) {
|
||||
printf("carplay connect timeout!\n");
|
||||
carlink_restart_bt_wifi();
|
||||
} else {
|
||||
pctx->mCarplayConnected = 0;
|
||||
carlink_bt_open();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_DISABLE_BT: {
|
||||
carlink_bt_close();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void carplay_iap_data_read(void* ctx, const void* buf, int len)
|
||||
{
|
||||
struct carplay_ctx* pctx = (struct carplay_ctx*)ctx;
|
||||
|
||||
if (!pctx->mIapReady)
|
||||
return;
|
||||
|
||||
iap2_read_data_proc((char*)buf, len);
|
||||
}
|
||||
|
||||
|
||||
static void taskInitCarlinkCpProc(void* param)
|
||||
{
|
||||
struct carplay_ctx* pctx = &g_cp_handle;
|
||||
struct carlink_event ev = {0};
|
||||
int ret = -1;
|
||||
#if 0
|
||||
carplay_init_parameter();
|
||||
carlink_bt_wifi_init();
|
||||
//start_mdnsd();
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
carplay_modules_test();
|
||||
vTaskDelete(NULL);
|
||||
return;
|
||||
#endif
|
||||
|
||||
(void)param;
|
||||
|
||||
iap2_callbacks iap2_cbs;
|
||||
memset((void *)&iap2_cbs, 0, sizeof(iap2_cbs));
|
||||
iap2_cbs.iap2_link_status_cb = iap2_link_status;
|
||||
iap2_cbs.iap2_write_data_cb = iap2_write_data;
|
||||
iap2_cbs.iap2_msg_time_update_cb = iap2_msg_time_update;
|
||||
iap2_cbs.iap2_msg_gps_cb = iap2_msg_gps;
|
||||
iap2_cbs.iap2_msg_gps_gprmc_data_status_cb = iap2_msg_gps_gprmc_data_status;
|
||||
iap2_cbs.iap2_msg_identify_cb = iap2_msg_identify;
|
||||
iap2_cbs.iap2_msg_wl_carplay_update_cb = iap2_msg_wl_carplay_update;
|
||||
iap2_cbs.iap2_msg_msg_json_cb = carplay_msg_notify;
|
||||
iap2_cbs.ctx = (void *)(NULL);
|
||||
iap2_register_callbacks(&iap2_cbs);
|
||||
|
||||
carplaySessionCbs carplay_cbs;
|
||||
memset((void *)&carplay_cbs, 0, sizeof(carplay_cbs));
|
||||
carplay_cbs.SessionStarted = carplay_session_started;
|
||||
carplay_cbs.SessionStop = carplay_session_Stop;
|
||||
carplay_cbs.SessionModesChanged = carplay_session_modes_changed;
|
||||
carplay_cbs.SessionRequestUI = carplay_session_requestUI;
|
||||
carplay_cbs.SessionDuckAudio = carplay_session_duck_audio;
|
||||
carplay_cbs.SessionUnduckAudio = carplay_session_unduck_audio;
|
||||
carplay_cbs.DisableBtSession = carplay_disable_bt_session;
|
||||
carplay_cbs.ViewAreaUpdateNotify = carplay_viewArea_update_notify;
|
||||
carplay_cbs.MsgNotify = carplay_msg_notify;
|
||||
carplay_cbs.ctx = (void *)(NULL);
|
||||
carplay_register_callbacks((void *)(&carplay_cbs));
|
||||
|
||||
video_callbacks_t video_cbs;
|
||||
memset((void *)&video_cbs, 0, sizeof(video_cbs));
|
||||
video_cbs.video_start_callback = video_start_callback_impl;
|
||||
video_cbs.video_stop_callback = video_stop_callback_impl;
|
||||
video_cbs.video_proc_data_callback = video_proc_data_callback_impl;
|
||||
video_cbs.ctx = NULL;
|
||||
video_register_callbacks((void *)(&video_cbs));
|
||||
|
||||
audio_callbacks_t audio_cbs;
|
||||
memset((void *)&audio_cbs, 0, sizeof(audio_cbs));
|
||||
audio_cbs.audio_start_callback = audio_start_callback_impl;
|
||||
audio_cbs.audio_stop_callback = audio_stop_callback_impl;
|
||||
audio_cbs.audio_reset_DSP_mode_callback = resetDspMode;
|
||||
audio_cbs.ctx = NULL;
|
||||
audio_register_callbacks((void *)(&audio_cbs));
|
||||
|
||||
set_carlink_display_info(0, 0, CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT);
|
||||
set_carlink_video_info(CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT, 30);
|
||||
carplay_init_parameter();
|
||||
|
||||
ret = carlink_common_init();
|
||||
if (0 != ret) {
|
||||
printf("%s:%d failed\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
pctx->carlinkEventCB.onEvent = onEventCarplay;
|
||||
pctx->carlinkEventCB.rfcomm_data_read = carplay_iap_data_read;
|
||||
pctx->carlinkEventCB.cb_ctx = (void*)pctx;
|
||||
|
||||
carlink_register_event_callbacks(&pctx->carlinkEventCB);
|
||||
|
||||
#if 1
|
||||
carlink_bt_wifi_init();
|
||||
carplay_init();
|
||||
|
||||
carplay_notify_event(&ev, CARLINK_EVENT_INIT_DONE, 0);
|
||||
#else
|
||||
carplay_modules_test();
|
||||
#endif
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void carplay_init_parameter()
|
||||
{
|
||||
g_link_info->link_type = CARPLAY_WIRELESS;
|
||||
|
||||
g_link_info->iap2_name = IAP2NAME;
|
||||
g_link_info->iap2_modelIdentifier = IAP2MODEID;
|
||||
g_link_info->iap2_manfacturer =MANFACTURER;
|
||||
g_link_info->iap2_serialnumber = SERIALNUMBER;
|
||||
g_link_info->iap2_sw_ver = SWVER;
|
||||
g_link_info->iap2_hw_ver = HWVER;
|
||||
g_link_info->iap2_vehicleInfo_name = VEHICLENAME;
|
||||
g_link_info->iap2_product_uuid = "101375-0068";
|
||||
|
||||
g_link_info->manfacturer = MANFACTURER;
|
||||
g_link_info->oem_icon_label = OEMICONLABEL;
|
||||
g_link_info->oem_icon_path = OEMICONPATH;
|
||||
g_link_info->os_info = OSINFO;
|
||||
g_link_info->iOSVersionMin = iOS_VER_MIN;
|
||||
g_link_info->limited_ui_elements = LIMITEDUIELEMENTS;
|
||||
g_link_info->guuid = DEFAULTUUID;
|
||||
g_link_info->devid = DEFAULTDEVID;
|
||||
|
||||
g_link_info->oem_icon_visible = 0;//ISOEMICONVISIBLE;
|
||||
g_link_info->limited_ui = ISLIMITEDUI;
|
||||
g_link_info->right_hand_driver = ISRIGHTHANDDRIVER;
|
||||
g_link_info->night_mode = 0;
|
||||
g_link_info->has_knob = HAS_KNOB;
|
||||
g_link_info->has_telbutton = 1;
|
||||
g_link_info->has_mediabutton = 1;
|
||||
g_link_info->has_proxsensor = HAS_PROXSENSOR;
|
||||
g_link_info->has_EnhancedReqCarUI = HAS_EnhancedRequestCarUI;
|
||||
g_link_info->has_ETCSupported = HAS_ETC;
|
||||
g_link_info->HiFiTouch = 1;
|
||||
g_link_info->LoFiTouch = 0;
|
||||
|
||||
g_link_info->usb_country_code = kUSBCountryCodeUS;
|
||||
g_link_info->tp_verndor_code = kUSBVendorTouchScreen;
|
||||
g_link_info->tp_product_code = kUSBProductTouchScreen;
|
||||
g_link_info->tel_verndor_code = kUSBVendorTeleButtons;
|
||||
g_link_info->tel_product_code = kUSBProductTeleButtons;
|
||||
g_link_info->knob_verndor_code = kUSBVendorKnobButtons;
|
||||
g_link_info->knob_product_code = kUSBProductKnobButtons;
|
||||
g_link_info->proxsensor_verndor_code = kUSBVendorProxSensor;
|
||||
g_link_info->proxsensor_product_code = kUSBProductProxSensor;
|
||||
|
||||
g_link_info->width = CARLINK_VIDEO_WIDTH;//pixel
|
||||
g_link_info->height = CARLINK_VIDEO_HEIGHT;
|
||||
g_link_info->fps = 30;
|
||||
g_link_info->screen_width_phy = PHYSICAL_WIDTH;//mm
|
||||
g_link_info->screen_height_phy = PHYSICAL_HEIGHT;
|
||||
|
||||
g_link_info->icurrent = 1000;
|
||||
g_link_info->enable_iap_carplay_sess = 1;
|
||||
g_link_info->keychain_path_dir = "/sf";
|
||||
g_link_info->is_old_carplay_ver = 0;
|
||||
g_link_info->enable_single_ui = 1;
|
||||
|
||||
g_link_info->disable_carplay_audio = 1;//1. audio is stream to bt;
|
||||
|
||||
//g_link_info->mfi_ic_addr = 0x22; //cp2.0
|
||||
g_link_info->mfi_ic_addr = 0x20; //cp3.0
|
||||
g_link_info->mfi_ic_i2c_bus_num = 0;
|
||||
|
||||
g_link_info->area[0].w = CARLINK_VIDEO_WIDTH;
|
||||
g_link_info->area[0].h = CARLINK_VIDEO_HEIGHT;
|
||||
g_link_info->area[0].x = 0;
|
||||
g_link_info->area[0].y = 0;
|
||||
|
||||
g_link_info->area[1].w = 1024;
|
||||
g_link_info->area[1].h = 600;
|
||||
g_link_info->area[1].x = 0;
|
||||
g_link_info->area[1].y = 0;
|
||||
|
||||
g_link_info->view_area_index = 0;
|
||||
|
||||
}
|
||||
|
||||
void carplay_modules_test();
|
||||
int carlink_cp_init()
|
||||
{
|
||||
xTaskCreate(taskInitCarlinkCpProc, "CpinitThread", 1024 * 32, NULL, configMAX_PRIORITIES / 4, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//int mdnsd_task();
|
||||
static void taskMdnsdProc(void* param)
|
||||
{
|
||||
//mdnsd_task();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void start_mdnsd()
|
||||
{
|
||||
xTaskCreate(taskMdnsdProc, "CpinitThread", 2048 * 4, NULL, 2, NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
int carlink_cp_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
6
app/carlink/CP/src/carlink_cp.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _CARLINK_CP_H_
|
||||
#define _CARLINK_CP_H_
|
||||
|
||||
int carlink_cp_init();
|
||||
|
||||
#endif
|
216
app/carlink/CP/src/carlink_cp_audio_impl.c
Normal file
@ -0,0 +1,216 @@
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <task.h>
|
||||
#include "os_adapt.h"
|
||||
#include "carlink_cp_priv.h"
|
||||
#include "carplay.h"
|
||||
#include "board.h"
|
||||
#include "audio.h"
|
||||
|
||||
|
||||
struct cp_audio_ctx
|
||||
{
|
||||
int handle;
|
||||
int type;
|
||||
int rate;
|
||||
int bits;
|
||||
int channels;
|
||||
|
||||
int start;
|
||||
int input;
|
||||
|
||||
struct audio_device *play_handle;
|
||||
struct audio_device *rec_handle;
|
||||
|
||||
pthread_t play_pid;
|
||||
pthread_t *play_pid_ptr;
|
||||
pthread_t rec_pid;
|
||||
pthread_t *rec_pid_ptr;
|
||||
};
|
||||
|
||||
struct audio_node
|
||||
{
|
||||
struct cp_audio_ctx entity;
|
||||
int isUse;
|
||||
};
|
||||
static struct audio_node gnode[8];
|
||||
static pthread_mutex_t g_node_lock = { \
|
||||
.xIsInitialized = pdFALSE, \
|
||||
.xMutex = { { 0 } }, \
|
||||
.xTaskOwner = NULL, \
|
||||
.xAttr = { .iType = 0 } \
|
||||
};
|
||||
|
||||
uint64_t UpTicks( void );
|
||||
|
||||
|
||||
static struct cp_audio_ctx* get_free_audio_node()
|
||||
{
|
||||
int i;
|
||||
struct cp_audio_ctx *pctx = NULL;
|
||||
struct audio_node* ptr= gnode;
|
||||
|
||||
pthread_mutex_lock(&g_node_lock);
|
||||
for (i = 0; i < ARRAY_SIZE(gnode); i++) {
|
||||
if (!ptr[i].isUse) {
|
||||
ptr[i].isUse = 1;
|
||||
pctx = &ptr[i].entity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_node_lock);
|
||||
return pctx;
|
||||
}
|
||||
|
||||
static struct cp_audio_ctx* get_audio_node_by_handle(int handle)
|
||||
{
|
||||
int i;
|
||||
struct cp_audio_ctx *pctx = NULL;
|
||||
struct audio_node* ptr= gnode;
|
||||
|
||||
pthread_mutex_lock(&g_node_lock);
|
||||
for (i = 0; i < ARRAY_SIZE(gnode); i++) {
|
||||
if (ptr[i].isUse) {
|
||||
struct cp_audio_ctx *tmp = &ptr[i].entity;
|
||||
if (tmp->handle == handle) {
|
||||
pctx = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_node_lock);
|
||||
return pctx;
|
||||
}
|
||||
|
||||
|
||||
static void release_audio_node(struct cp_audio_ctx *pctx)
|
||||
{
|
||||
int i;
|
||||
struct audio_node* ptr= gnode;
|
||||
if (NULL == pctx)
|
||||
return;
|
||||
|
||||
memset((void*)pctx, 0, sizeof(struct cp_audio_ctx));
|
||||
pthread_mutex_lock(&g_node_lock);
|
||||
for (i = 0; i < ARRAY_SIZE(gnode); i++) {
|
||||
if (pctx == &ptr[i].entity) {
|
||||
ptr[i].isUse = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_node_lock);
|
||||
}
|
||||
|
||||
static void * _AudioStreamRecordThread( void *inArg )
|
||||
{
|
||||
struct cp_audio_ctx* pctx = (struct cp_audio_ctx*)inArg;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void * _AudioStreamPlayThread( void *inArg )
|
||||
{
|
||||
struct cp_audio_ctx* pctx = (struct cp_audio_ctx*)inArg;
|
||||
uint8_t buffer[960];
|
||||
int buffer_len = 960;
|
||||
int frame;
|
||||
|
||||
frame = 960 / (pctx->channels * pctx->channels / 8);
|
||||
|
||||
process_play_stream(pctx->handle, buffer, buffer_len, frame, UpTicks());
|
||||
|
||||
while(pctx->start) {
|
||||
process_play_stream(pctx->handle, buffer, buffer_len, frame, UpTicks());
|
||||
audio_dev_write(pctx->play_handle, buffer, buffer_len);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int carlink_cp_audio_start(int handle, int type, int rate, int bits, int channels)
|
||||
{
|
||||
int ret = -1;
|
||||
struct cp_audio_ctx* pctx = NULL;
|
||||
struct audio_caps caps = {0};
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setstacksize(&attr, 4096 * 12);
|
||||
|
||||
pctx = get_free_audio_node();
|
||||
if (NULL == pctx) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pctx->bits = bits;
|
||||
pctx->channels = channels;
|
||||
pctx->rate = rate;
|
||||
pctx->type = type;
|
||||
pctx->handle = handle;
|
||||
|
||||
if (type == AUDIO_TELEPHONE || type == AUDIO_RECOGNITION) {
|
||||
pctx->input = 1;
|
||||
}
|
||||
|
||||
pctx->play_handle = audio_dev_open(AUDIO_FLAG_REPLAY);
|
||||
caps.main_type = AUDIO_TYPE_OUTPUT;
|
||||
caps.sub_type = AUDIO_DSP_PARAM;
|
||||
caps.udata.config.samplerate = rate;
|
||||
caps.udata.config.channels = channels;
|
||||
caps.udata.config.samplebits = bits;
|
||||
audio_dev_configure(pctx->play_handle, &caps);
|
||||
|
||||
pctx->start = 1;
|
||||
if (pctx->input) {
|
||||
pctx->rec_handle = audio_dev_open(AUDIO_FLAG_RECORD);
|
||||
caps.main_type = AUDIO_TYPE_OUTPUT;
|
||||
caps.sub_type = AUDIO_DSP_PARAM;
|
||||
caps.udata.config.samplerate = rate;
|
||||
caps.udata.config.channels = channels;
|
||||
caps.udata.config.samplebits = bits;
|
||||
audio_dev_configure(pctx->play_handle, &caps);
|
||||
ret = pthread_create( &pctx->rec_pid, &attr, _AudioStreamRecordThread, (void*)pctx );
|
||||
if (ret == 0) {
|
||||
pctx->rec_pid_ptr = &pctx->rec_pid;
|
||||
}
|
||||
}
|
||||
|
||||
ret = pthread_create( &pctx->play_pid, &attr, _AudioStreamPlayThread, (void*)pctx );
|
||||
if (ret == 0) {
|
||||
pctx->play_pid_ptr = &pctx->play_pid;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void carlink_cp_audio_stop(int handle, int type)
|
||||
{
|
||||
struct cp_audio_ctx *pctx = NULL;
|
||||
|
||||
pctx = get_audio_node_by_handle(handle);
|
||||
|
||||
if (NULL == pctx || !pctx->start)
|
||||
return;
|
||||
|
||||
pctx->start = 0;
|
||||
|
||||
if (pctx->play_pid_ptr) {
|
||||
pthread_join(pctx->play_pid, NULL);
|
||||
pctx->play_pid_ptr = NULL;
|
||||
}
|
||||
|
||||
if (pctx->rec_pid_ptr) {
|
||||
pthread_join(pctx->rec_pid, NULL);
|
||||
pctx->rec_pid_ptr = NULL;
|
||||
}
|
||||
|
||||
release_audio_node(pctx);
|
||||
}
|
||||
|
53
app/carlink/CP/src/carlink_cp_priv.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef __CARLINK_CP_PRI_H
|
||||
#define __CARLINK_CP_PRI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IAP2NAME "KY CAR"
|
||||
#define IAP2MODEID "Linux"
|
||||
#define SERIALNUMBER "0123456789ABCDEF"
|
||||
#define SWVER "sw0.1"
|
||||
#define HWVER "hw0.1"
|
||||
#define VEHICLENAME "audi"
|
||||
|
||||
#define MANFACTURER "ARK"
|
||||
#define OEMICONLABEL "Home"
|
||||
#define OEMICONPATH "/sf/carplay_icon.png"
|
||||
#define OSINFO "rtos"
|
||||
#define iOS_VER_MIN "11D257"
|
||||
//#define LIMITEDUIELEMENTS "softKeyboard"
|
||||
#define LIMITEDUIELEMENTS "japanMaps"
|
||||
#define DEFAULTUUID "e5f7b72d-9b7f-4305-954b-973f612a150b"
|
||||
#define DEFAULTDEVID "10:13:52:33:67:09"
|
||||
#define ISOEMICONVISIBLE 1
|
||||
#define ISRIGHTHANDDRIVER 0
|
||||
#define ISLIMITEDUI 1
|
||||
#define HAS_KNOB 1
|
||||
#define HAS_PROXSENSOR 0
|
||||
#define HAS_ETC 0
|
||||
#define HAS_EnhancedRequestCarUI 0
|
||||
|
||||
#define kUSBCountryCodeUS 33
|
||||
#define kUSBVendorTouchScreen 0x0525
|
||||
#define kUSBProductTouchScreen 0xa4a1
|
||||
#define kUSBVendorTeleButtons 0x0525
|
||||
#define kUSBProductTeleButtons 0xa4a2
|
||||
#define kUSBVendorKnobButtons 0x0525
|
||||
#define kUSBProductKnobButtons 0xa4a2
|
||||
#define kUSBVendorProxSensor 0
|
||||
#define kUSBProductProxSensor 0
|
||||
|
||||
#define PHYSICAL_WIDTH 160
|
||||
#define PHYSICAL_HEIGHT 80
|
||||
|
||||
void carplay_modules_test();
|
||||
int carlink_cp_audio_start(int handle, int type, int rate, int bits, int channels);
|
||||
void carlink_cp_audio_stop(int handle, int type);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
345
app/carlink/EC-orig/include/ECTiny.h
Normal file
@ -0,0 +1,345 @@
|
||||
#ifndef __ECTINY_API_H__
|
||||
#define __ECTINY_API_H__
|
||||
|
||||
#include "ECTypes.h"
|
||||
|
||||
#define ECSDK_VERSION "1.0.8.1"
|
||||
|
||||
typedef struct {
|
||||
|
||||
void (*onECConnectStatus)(ECConnectedStatus status, ECConnectedType type);
|
||||
|
||||
void (*onMirrorStatus)(ECMirrorStatus status);
|
||||
/**
|
||||
* @brief Called when EasyConnected status changed.
|
||||
*
|
||||
* @param status The changed EasyConnected message.
|
||||
*/
|
||||
void (*onECStatusMessage)(ECStatusMessage status);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD information.
|
||||
*
|
||||
* @param data HUD information.
|
||||
*/
|
||||
void (*onPhoneAppHUD)(const ECNavigationHudInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD Road Junction Picture.
|
||||
* @param data
|
||||
*/
|
||||
void (*onPhoneAppHUDRoadJunctionPicture)(const ECHudRoadJunctionPictureInfo* data);
|
||||
|
||||
/*
|
||||
* @brief Called when phone app tell the music info.
|
||||
*
|
||||
* @param data The information of music.
|
||||
*/
|
||||
void (*onPhoneAppMusicInfo)(const ECAppMusicInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down some information.
|
||||
*
|
||||
* @param data Buffer of app information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data is json string, the fields includes os, osVersion and ip.
|
||||
* Called when ECSDK::openTransport succeed.
|
||||
*/
|
||||
void (*onPhoneAppInfo)(const void *data, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when ECSDK wants car to do call operations(dial or hang up) via Bluetooth.
|
||||
*
|
||||
* @param type Operation type.
|
||||
*
|
||||
* @param name The person's name of corresponding number.
|
||||
*
|
||||
* @param number Phone numbers.
|
||||
*
|
||||
* @note Phone app is not able to dial or hang up automatically due to the latest system access limitation,
|
||||
* however, car is able to do it via Bluetooth. Therefore, ECSDK moves the call operations
|
||||
* to car, which can dial or hang up when this method is called.
|
||||
*/
|
||||
void (*onCallAction)(ECCallType type, const char *name, const char *number);
|
||||
|
||||
/**
|
||||
* @brief Called when bulk data is received.
|
||||
*
|
||||
* @param data Buffer of bulk data.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
*/
|
||||
void (*onBulkDataReceived)(const void *data, uint32_t length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief onRealMirrorSizeChanged
|
||||
* @param realWidth
|
||||
* @param realHeight
|
||||
*
|
||||
* \note The actual size of the projection screen does not equal the size of the video stream in some cases.
|
||||
* The surrounding area is filled with black. This message calls back the actual size of the projection screen
|
||||
*/
|
||||
void (*onMirrorInfoChanged)(const ECVideoInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization failed. After this interface was called,
|
||||
* all connections would be forced closed.
|
||||
*
|
||||
* @param errCode Error code.
|
||||
*
|
||||
* @param errMsg Error message.
|
||||
*/
|
||||
void (*onLicenseAuthFail)(int32_t errCode, const char *errMsg);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization succeed.
|
||||
*
|
||||
* @param code success code. The code can gain specific meaning by ECAuthSuccessCode.
|
||||
*
|
||||
* @param msg success information.
|
||||
*
|
||||
* @param msg the description information.
|
||||
*
|
||||
*/
|
||||
void (*onLicenseAuthSuccess)(int32_t code, const char *msg);
|
||||
|
||||
/**
|
||||
* @brief Called when registered command was triggered by VR.
|
||||
*
|
||||
* @param carCmd The triggered command.
|
||||
*
|
||||
* @note Voice control can be implemented with this method by VR.
|
||||
*
|
||||
* @see ECSDK::registerCarCmds
|
||||
*/
|
||||
void (*onCarCmdNotified)(const ECCarCmd *carCmd);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to start input.
|
||||
*
|
||||
* @param info relevant parameters about the input.
|
||||
*/
|
||||
void (*onInputStart)(const ECInputInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to cancel input.
|
||||
*/
|
||||
void (*onInputCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the selection of input.
|
||||
*/
|
||||
void (*onInputSelection)(int32_t start, int32_t stop);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the text of input.
|
||||
*/
|
||||
void (*onInputText)(const char *text);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app send the text of VR or TTS.
|
||||
*/
|
||||
void (*onVRTextReceived)(const ECVRTextInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the page list.
|
||||
*
|
||||
* @param pages Array of the struct ECPageInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
*/
|
||||
void (*onPageListReceived)(const ECPageInfo *pages, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the icons.
|
||||
*
|
||||
* @param icons Array of the struct ECIconInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
*/
|
||||
void (*onPageIconReceived)(const ECIconInfo *icons, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell weather.
|
||||
*
|
||||
* @param data Buffer of weather information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
*/
|
||||
void (*onWeatherReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell vr tips.
|
||||
*
|
||||
* @param data Buffer of tips information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
*/
|
||||
void (*onVRTipsReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when the app requests networking
|
||||
*
|
||||
* @param clientInfo Mobile phone related information
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onRequestBuildNet)(const ECBTClientInfo *clientInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when canceling networking
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onRequestBuildNetCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when networking is completed
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onPhoneBuildNetFinish)();
|
||||
|
||||
/**
|
||||
* @brief Called when app sends AP information
|
||||
*
|
||||
* @param netDeviceInfo AP information
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onPhoneAPInfo)(const ECBTNetInfo* netDeviceInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when mobile phone has a notification message.
|
||||
* @param notification
|
||||
*/
|
||||
void (*onPhoneNotification)(const ECPhoneNotification* notification);
|
||||
} IECCallBack;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t (*size)(const char* name);
|
||||
int32_t (*read)(const char* name,void *data, uint32_t length);
|
||||
int32_t (*write)(const char* name,void *data, uint32_t length);
|
||||
void (*clear)(const char* name);
|
||||
}IECAccessFile;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*open)();
|
||||
int32_t (*read)(void *data, uint32_t length);
|
||||
int32_t (*write)(void *data, uint32_t length);
|
||||
void (*close)();
|
||||
}IECAccessDevice;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t (*registHid)(uint32_t deviceId,uint32_t descriptorSize);
|
||||
void (*unRegistHid)(uint32_t deviceId);
|
||||
uint32_t (*sendHiDDescriptor)(uint32_t deviceId, const unsigned char* descriptor, uint32_t len);
|
||||
uint32_t (*sendHidEvent)(uint32_t deviceId, const unsigned char* event, uint32_t len);
|
||||
}IECHidAccessDev;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*open)();
|
||||
int32_t (*read)(uint8_t* data, uint32_t len);
|
||||
int32_t (*write)(const uint8_t* data, uint32_t len);
|
||||
int32_t (*close)();
|
||||
}IECBTAccessDev;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*start)(int32_t width, int32_t height);
|
||||
void (*stop)();
|
||||
void (*play)(const void *data, uint32_t len);
|
||||
}IECVideoPlayer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*start)(ECAudioType type, const ECAudioInfo *info);
|
||||
void (*stop)(ECAudioType type);
|
||||
void (*play)(ECAudioType type, const void *data, uint32_t len);
|
||||
void (*setVolume)(ECAudioType type, uint32_t vol);
|
||||
}IECAudioPlayer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*start)(const ECAudioInfo *info);
|
||||
void (*stop)();
|
||||
int32_t (*record)(void *data, uint32_t len);
|
||||
}IECAudioRecorder;
|
||||
|
||||
typedef void *ECConfigHandle;
|
||||
|
||||
ECConfigHandle EC_createECConfig();
|
||||
void EC_destroyECConfig(ECConfigHandle config);
|
||||
void EC_setBaseConfig(ECConfigHandle config,const char *uuid, const char *version,const char *writableDir);
|
||||
void EC_setCommonConfig(ECConfigHandle config, const char *cfgName, const char *value);
|
||||
void EC_setCommonConfig1(ECConfigHandle config, const char *cfgName, int32_t value);
|
||||
|
||||
int32_t EC_initialize(ECConfigHandle config, IECCallBack *listener);
|
||||
int32_t EC_release();
|
||||
int32_t EC_setLogInfo(const ECLogLevel level,const ECLogOutputType type,const char *logDirectory, int32_t module);
|
||||
const char* EC_getVersion();
|
||||
int32_t EC_getVersionCode();
|
||||
int32_t EC_start();
|
||||
int32_t EC_stop();
|
||||
int32_t EC_bindAccessFile(IECAccessFile *handle);
|
||||
int32_t EC_bindUSBDevice(ECTransportType type, IECAccessDevice *dev);
|
||||
int32_t EC_bindWIFIDevice(ECTransportType type, const char *ip);
|
||||
int32_t EC_unbindDevice(ECTransportType type);
|
||||
int32_t EC_bindHidDevice(IECHidAccessDev* dev);
|
||||
int32_t EC_unBindHidDevice();
|
||||
int32_t EC_bindBTDevice( IECAccessDevice* ioHandle);
|
||||
int32_t EC_unBindBTDevice();
|
||||
int32_t EC_setMirrorConfig(const ECMirrorConfig *mirrorCfg);
|
||||
int32_t EC_setVideoPlayer(IECVideoPlayer* video);
|
||||
int32_t EC_setAudioPlayer(IECAudioPlayer* audio);
|
||||
int32_t EC_setAudioRecorder(IECAudioRecorder* audioRecorde);
|
||||
int32_t EC_notifyWifiStateChanged(ECWifiStateAction action, const ECNetWorkInfo* netInfo);
|
||||
int32_t EC_setRequestBuildNetRly(const char *phoneID, const ECBTRequestBuildNetRly *rly);
|
||||
int32_t EC_setNetInterfaceInfo(const ECNetInterfaceInfo *info,const int32_t num);
|
||||
int32_t EC_startMirror();
|
||||
void EC_stopMirror();
|
||||
int32_t EC_pauseMirror();
|
||||
int32_t EC_resumeMirror();
|
||||
int32_t EC_sendTouchEvent(const ECTouchEventData *touch, ECTouchEventType type);
|
||||
int32_t EC_sendBtnEvent(int32_t btnCode, int32_t type);
|
||||
int32_t EC_stopPhoneNavigation();
|
||||
int32_t EC_stopPhoneVR();
|
||||
int32_t EC_uploadNightModeStatus(uint32_t isNightModeOn);
|
||||
int32_t EC_uploadDrivingStatus(ECDrivingStatus status);
|
||||
int32_t EC_enableDownloadPhoneAppAudio(uint32_t supportType, uint32_t autoChangeToBT);
|
||||
void EC_disableDownloadPhoneAppAudio();
|
||||
int32_t EC_enableDownloadPhoneAppHud(uint32_t supportFunction);
|
||||
void EC_disableDownloadPhoneAppHud();
|
||||
int32_t EC_setConnectedBTAddress(const char *carBtMac, const char *phoneBtMac);
|
||||
int32_t EC_sendCarBluetooth(const char *name, const char *adddress, const char *pin);
|
||||
int32_t EC_openAppPage(int32_t page);
|
||||
int32_t EC_queryGPS(uint32_t* status, ECGPSInfo* gps);
|
||||
int32_t EC_queryTime(uint64_t *gmtTime, uint64_t *localTime, char *timeZone, uint32_t len);
|
||||
int32_t EC_sendCarStatus(ECCarStatusType carStatus, ECCarStatusValue value);
|
||||
int32_t EC_registerCarCmds(const ECCarCmd *carCmds, uint32_t length);
|
||||
int32_t EC_playCarTTS(const char *text, uint32_t level);
|
||||
int32_t EC_registerSimilarSoundingWords(const char *data, uint32_t length);
|
||||
int32_t EC_sendInputText(const char* text);
|
||||
int32_t EC_sendInputAction(int32_t actionId, int32_t keyCode);
|
||||
int32_t EC_sendInputSelection(int32_t start, int32_t stop);
|
||||
int32_t EC_queryPageList();
|
||||
int32_t EC_queryPageIcon(int32_t* pages, int32_t length);
|
||||
int32_t EC_queryWeather();
|
||||
int32_t EC_queryVRTips();
|
||||
const char* EC_generateQRCodeUrl(ECQRInfo* info);
|
||||
int32_t EC_startIperfTcpServer(const char* ip, int port);
|
||||
void EC_stopIperfTcpServer();
|
||||
#endif
|
||||
|
1428
app/carlink/EC-orig/include/ECTypes.h
Normal file
BIN
app/carlink/EC-orig/lib/ECTiny.a
Normal file
1095
app/carlink/EC-orig/src/carlink_ec.c
Normal file
6
app/carlink/EC-orig/src/carlink_ec.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _CARLINK_EC_H_
|
||||
#define _CARLINK_EC_H_
|
||||
|
||||
int carlink_ec_init(int argc,char ** argv);
|
||||
|
||||
#endif
|
417
app/carlink/EC/include/ECTiny.h
Normal file
@ -0,0 +1,417 @@
|
||||
#ifndef __ECTINY_API_H__
|
||||
#define __ECTINY_API_H__
|
||||
|
||||
#include "ECTypes.h"
|
||||
|
||||
#define ECSDK_VERSION "1.0.10"
|
||||
|
||||
typedef struct {
|
||||
|
||||
void (*onECConnectStatus)(ECConnectedStatus status, ECConnectedType type);
|
||||
|
||||
void (*onMirrorStatus)(ECMirrorStatus status);
|
||||
/**
|
||||
* @brief Called when EasyConnected status changed.
|
||||
*
|
||||
* @param status The changed EasyConnected message.
|
||||
*/
|
||||
void (*onECStatusMessage)(ECStatusMessage status);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD information.
|
||||
*
|
||||
* @param data HUD information.
|
||||
*/
|
||||
void (*onPhoneAppHUD)(const ECNavigationHudInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD Road Junction Picture.
|
||||
* @param data
|
||||
*/
|
||||
void (*onPhoneAppHUDRoadJunctionPicture)(const ECHudRoadJunctionPictureInfo* data);
|
||||
|
||||
/*
|
||||
* @brief Called when phone app tell the music info.
|
||||
*
|
||||
* @param data The information of music.
|
||||
*/
|
||||
void (*onPhoneAppMusicInfo)(const ECAppMusicInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down some information.
|
||||
*
|
||||
* @param data Buffer of app information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data is json string, the fields includes os, osVersion and ip.
|
||||
* Called when ECSDK::openTransport succeed.
|
||||
*/
|
||||
void (*onPhoneAppInfo)(const void *data, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when ECSDK wants car to do call operations(dial or hang up) via Bluetooth.
|
||||
*
|
||||
* @param type Operation type.
|
||||
*
|
||||
* @param name The person's name of corresponding number.
|
||||
*
|
||||
* @param number Phone numbers.
|
||||
*
|
||||
* @note Phone app is not able to dial or hang up automatically due to the latest system access limitation,
|
||||
* however, car is able to do it via Bluetooth. Therefore, ECSDK moves the call operations
|
||||
* to car, which can dial or hang up when this method is called.
|
||||
*/
|
||||
void (*onCallAction)(ECCallType type, const char *name, const char *number);
|
||||
|
||||
/**
|
||||
* @brief Called when bulk data is received.
|
||||
*
|
||||
* @param data Buffer of bulk data.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
*/
|
||||
void (*onBulkDataReceived)(const void *data, uint32_t length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief onRealMirrorSizeChanged
|
||||
* @param realWidth
|
||||
* @param realHeight
|
||||
*
|
||||
* \note The actual size of the projection screen does not equal the size of the video stream in some cases.
|
||||
* The surrounding area is filled with black. This message calls back the actual size of the projection screen
|
||||
*/
|
||||
void (*onMirrorInfoChanged)(const ECVideoInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization failed. After this interface was called,
|
||||
* all connections would be forced closed.
|
||||
*
|
||||
* @param errCode Error code.
|
||||
*
|
||||
* @param errMsg Error message.
|
||||
*/
|
||||
void (*onLicenseAuthFail)(int32_t errCode, const char *errMsg);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization succeed.
|
||||
*
|
||||
* @param code success code. The code can gain specific meaning by ECAuthSuccessCode.
|
||||
*
|
||||
* @param msg success information.
|
||||
*
|
||||
* @param msg the description information.
|
||||
*
|
||||
*/
|
||||
void (*onLicenseAuthSuccess)(int32_t code, const char *msg);
|
||||
|
||||
/**
|
||||
* @brief Called when registered command was triggered by VR.
|
||||
*
|
||||
* @param carCmd The triggered command.
|
||||
*
|
||||
* @note Voice control can be implemented with this method by VR.
|
||||
*
|
||||
* @see ECSDK::registerCarCmds
|
||||
*/
|
||||
void (*onCarCmdNotified)(const ECCarCmd *carCmd);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to start input.
|
||||
*
|
||||
* @param info relevant parameters about the input.
|
||||
*/
|
||||
void (*onInputStart)(const ECInputInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to cancel input.
|
||||
*/
|
||||
void (*onInputCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the selection of input.
|
||||
*/
|
||||
void (*onInputSelection)(int32_t start, int32_t stop);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the text of input.
|
||||
*/
|
||||
void (*onInputText)(const char *text);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app send the text of VR or TTS.
|
||||
*/
|
||||
void (*onVRTextReceived)(const ECVRTextInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the page list.
|
||||
*
|
||||
* @param pages Array of the struct ECPageInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
*/
|
||||
void (*onPageListReceived)(const ECPageInfo *pages, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the icons.
|
||||
*
|
||||
* @param icons Array of the struct ECIconInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
*/
|
||||
void (*onPageIconReceived)(const ECIconInfo *icons, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell weather.
|
||||
*
|
||||
* @param data Buffer of weather information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
*/
|
||||
void (*onWeatherReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell vr tips.
|
||||
*
|
||||
* @param data Buffer of tips information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
*/
|
||||
void (*onVRTipsReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when the app requests networking
|
||||
*
|
||||
* @param clientInfo Mobile phone related information
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onRequestBuildNet)(const ECBTClientInfo *clientInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when canceling networking
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onRequestBuildNetCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when networking is completed
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onPhoneBuildNetFinish)();
|
||||
|
||||
/**
|
||||
* @brief Called when app sends AP information
|
||||
*
|
||||
* @param netDeviceInfo AP information
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onPhoneAPInfo)(const ECBTNetInfo* netDeviceInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when mobile phone has a notification message.
|
||||
* @param notification
|
||||
*/
|
||||
void (*onPhoneNotification)(const ECPhoneNotification* notification);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD lane guidance Picture.
|
||||
* @param notification
|
||||
*/
|
||||
void (*onPhoneAppHUDLaneGuidancePicture)(const ECHudLaneGuidancePictureInfo * data);
|
||||
|
||||
/**
|
||||
* @brief Called when checkOTAUpdate was called, it will tell the result of checkOTAUpdate.
|
||||
*
|
||||
* @param downloadableSoftwares It pointer to a array of ECOTAUpdateSoftware, which is downloadable software.
|
||||
*
|
||||
* @param downloadableLength The length of the downloadable array, if downloadableLength < 0, means check occur error, downloadableLength is error value of ECOTAUpdateErrorCode.
|
||||
*
|
||||
* @param downloadedSoftwares It pointer to a array of ECOTAUpdateSoftware, which is downloaded software.
|
||||
*
|
||||
* @param downloadedLength The length of the downloaded array.
|
||||
*/
|
||||
void (*onOTAUpdateCheckResult)(const ECOTAUpdateSoftware* downloadableSoftwares, const int32_t downloadableLength, const ECOTAUpdateSoftware* downloadedSoftwares, const uint32_t downloadedLength);
|
||||
|
||||
/**
|
||||
* @brief Called when remote downloadable software has been downloaded to phone.
|
||||
*
|
||||
* @param downloadableSoftwares It pointer to a array of ECOTAUpdateSoftware, which has been in phone, can be downloaded from phone to HU.
|
||||
*
|
||||
* @param downloadableLength The length of the downloadable array.
|
||||
*/
|
||||
void (*onOTAUpdateRequestDownload)(const ECOTAUpdateSoftware* downloadableSoftwares, const uint32_t downloadableLength);
|
||||
|
||||
/**
|
||||
* @brief Called when startOTAUpdate is called, it will notify the progress of downloading.
|
||||
*
|
||||
* @param downloadingSoftwareId The id of the downloading software.
|
||||
*
|
||||
* @param progress The progress of the downloading software,which is a percentage.
|
||||
*
|
||||
* @param softwareLeftTime The left time of the downloading software.
|
||||
*
|
||||
* @param otaLeftTime The left time of all the specified software by startOTAUpdate.
|
||||
*/
|
||||
void (*onOTAUpdateProgress)(const char* downloadingSoftwareId, float progress, uint32_t softwareLeftTime, uint32_t otaLeftTime);
|
||||
|
||||
/**
|
||||
* @brief Called when startOTAUpdate is called, it will notify software is downloaded.
|
||||
*
|
||||
* @param downloadedSoftwareId The id of the downloaded software.
|
||||
*
|
||||
* @param md5Path The md5 file path.
|
||||
*
|
||||
* @param packagePath The software path.
|
||||
*
|
||||
* @param iconPath The icon path.
|
||||
*
|
||||
* @param leftSoftwareNum The amount of software remaining to be downloaded.
|
||||
*/
|
||||
void (*onOTAUpdateCompleted)(const char* downloadedSoftwareId, const char* md5Path, const char* packagePath, const char* iconPath, uint32_t leftSoftwareNum);
|
||||
|
||||
/**
|
||||
* @brief Called when checkOTAUpdate or startOTAUpdate failed.
|
||||
*
|
||||
* @param errCode error code, see ECOTAUpdateErrorCode.
|
||||
*
|
||||
* @param softwarId the id of software.
|
||||
*/
|
||||
void (*onOTAUpdateError)(int32_t errCode, const char* softwareId);
|
||||
|
||||
} IECCallBack;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t (*size)(const char* name);
|
||||
int32_t (*read)(const char* name,void *data, uint32_t length, uint32_t offset);
|
||||
int32_t (*write)(const char* name,void *data, uint32_t length, uint32_t offset);
|
||||
void (*clear)(const char* name);
|
||||
}IECAccessFile;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*open)();
|
||||
int32_t (*read)(void *data, uint32_t length);
|
||||
int32_t (*write)(void *data, uint32_t length);
|
||||
void (*close)();
|
||||
}IECAccessDevice;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t (*registHid)(uint32_t deviceId,uint32_t descriptorSize);
|
||||
void (*unRegistHid)(uint32_t deviceId);
|
||||
uint32_t (*sendHiDDescriptor)(uint32_t deviceId, const unsigned char* descriptor, uint32_t len);
|
||||
uint32_t (*sendHidEvent)(uint32_t deviceId, const unsigned char* event, uint32_t len);
|
||||
}IECHidAccessDev;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*open)();
|
||||
int32_t (*read)(uint8_t* data, uint32_t len);
|
||||
int32_t (*write)(const uint8_t* data, uint32_t len);
|
||||
int32_t (*close)();
|
||||
}IECBTAccessDev;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*start)(int32_t width, int32_t height);
|
||||
void (*stop)();
|
||||
void (*play)(const void *data, uint32_t len);
|
||||
}IECVideoPlayer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*start)(ECAudioType type, const ECAudioInfo *info);
|
||||
void (*stop)(ECAudioType type);
|
||||
void (*play)(ECAudioType type, const void *data, uint32_t len);
|
||||
void (*setVolume)(ECAudioType type, uint32_t vol);
|
||||
}IECAudioPlayer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*start)(const ECAudioInfo *info);
|
||||
void (*stop)();
|
||||
int32_t (*record)(void *data, uint32_t len);
|
||||
}IECAudioRecorder;
|
||||
|
||||
typedef void *ECConfigHandle;
|
||||
|
||||
ECConfigHandle EC_createECConfig();
|
||||
void EC_destroyECConfig(ECConfigHandle config);
|
||||
void EC_setBaseConfig(ECConfigHandle config,const char *uuid, const char *version,const char *writableDir);
|
||||
void EC_setCommonConfig(ECConfigHandle config, const char *cfgName, const char *value);
|
||||
void EC_setCommonConfig1(ECConfigHandle config, const char *cfgName, int32_t value);
|
||||
|
||||
int32_t EC_initialize(ECConfigHandle config, IECCallBack *listener);
|
||||
int32_t EC_release();
|
||||
int32_t EC_setLogInfo(const ECLogLevel level,const ECLogOutputType type,const char *logDirectory, int32_t module);
|
||||
const char* EC_getVersion();
|
||||
int32_t EC_getVersionCode();
|
||||
int32_t EC_start();
|
||||
int32_t EC_stop();
|
||||
int32_t EC_bindAccessFile(IECAccessFile *handle);
|
||||
int32_t EC_bindUSBDevice(ECTransportType type, IECAccessDevice *dev);
|
||||
int32_t EC_bindWIFIDevice(ECTransportType type, const char *ip);
|
||||
int32_t EC_unbindDevice(ECTransportType type);
|
||||
int32_t EC_bindHidDevice(IECHidAccessDev* dev);
|
||||
int32_t EC_unBindHidDevice();
|
||||
int32_t EC_bindBTDevice( IECAccessDevice* ioHandle);
|
||||
int32_t EC_unBindBTDevice();
|
||||
int32_t EC_setMirrorConfig(const ECMirrorConfig *mirrorCfg);
|
||||
int32_t EC_setVideoPlayer(IECVideoPlayer* video);
|
||||
int32_t EC_setAudioPlayer(IECAudioPlayer* audio);
|
||||
int32_t EC_setAudioRecorder(IECAudioRecorder* audioRecorde);
|
||||
int32_t EC_notifyWifiStateChanged(ECWifiStateAction action, const ECNetWorkInfo* netInfo);
|
||||
int32_t EC_setRequestBuildNetRly(const char *phoneID, const ECBTRequestBuildNetRly *rly);
|
||||
int32_t EC_setNetInterfaceInfo(const ECNetInterfaceInfo *info,const int32_t num);
|
||||
int32_t EC_startMirror();
|
||||
void EC_stopMirror();
|
||||
int32_t EC_pauseMirror();
|
||||
int32_t EC_resumeMirror();
|
||||
int32_t EC_sendTouchEvent(const ECTouchEventData *touch, ECTouchEventType type);
|
||||
int32_t EC_sendBtnEvent(int32_t btnCode, int32_t type);
|
||||
int32_t EC_stopPhoneNavigation();
|
||||
int32_t EC_stopPhoneVR();
|
||||
int32_t EC_uploadNightModeStatus(uint32_t isNightModeOn);
|
||||
int32_t EC_uploadDrivingStatus(ECDrivingStatus status);
|
||||
int32_t EC_enableDownloadPhoneAppAudio(uint32_t supportType, uint32_t autoChangeToBT);
|
||||
void EC_disableDownloadPhoneAppAudio();
|
||||
int32_t EC_enableDownloadPhoneAppHud(uint32_t supportFunction);
|
||||
void EC_disableDownloadPhoneAppHud();
|
||||
int32_t EC_setConnectedBTAddress(const char *carBtMac, const char *phoneBtMac);
|
||||
int32_t EC_sendCarBluetooth(const char *name, const char *adddress, const char *pin);
|
||||
int32_t EC_openAppPage(int32_t page);
|
||||
int32_t EC_queryGPS(uint32_t* status, ECGPSInfo* gps);
|
||||
int32_t EC_queryTime(uint64_t *gmtTime, uint64_t *localTime, char *timeZone, uint32_t len, char* dateTime, uint32_t dateTimeLen);
|
||||
int32_t EC_sendCarStatus(ECCarStatusType carStatus, ECCarStatusValue value);
|
||||
int32_t EC_registerCarCmds(const ECCarCmd *carCmds, uint32_t length);
|
||||
int32_t EC_playCarTTS(const char *text, uint32_t level);
|
||||
int32_t EC_registerSimilarSoundingWords(const char *data, uint32_t length);
|
||||
int32_t EC_sendInputText(const char* text);
|
||||
int32_t EC_sendInputAction(int32_t actionId, int32_t keyCode);
|
||||
int32_t EC_sendInputSelection(int32_t start, int32_t stop);
|
||||
int32_t EC_queryPageList();
|
||||
int32_t EC_queryPageIcon(int32_t* pages, int32_t length);
|
||||
int32_t EC_queryWeather();
|
||||
int32_t EC_queryVRTips();
|
||||
const char* EC_generateQRCodeUrl(ECQRInfo* info);
|
||||
int32_t EC_requestPhoneNotification(int32_t enable);
|
||||
|
||||
int32_t EC_checkOTAUpdate(const ECOTAConfig* cfg, const ECLanguage language, const ECOTAUpdateCheckMode mode);
|
||||
int32_t EC_startOTAUpdate(const char** softwareIds, const int32_t softwareNum);
|
||||
void EC_stopOTAUpdate();
|
||||
|
||||
int32_t EC_startIperfTcpServer(const char* ip, int port);
|
||||
void EC_stopIperfTcpServer();
|
||||
#endif
|
||||
|
1525
app/carlink/EC/include/ECTypes.h
Normal file
BIN
app/carlink/EC/lib/ECTiny.a
Normal file
BIN
app/carlink/EC/lib/ECTiny_old.a
Normal file
1330
app/carlink/EC/src/carlink_ec.c
Normal file
6
app/carlink/EC/src/carlink_ec.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _CARLINK_EC_H_
|
||||
#define _CARLINK_EC_H_
|
||||
|
||||
int carlink_ec_init(int argc,char ** argv);
|
||||
|
||||
#endif
|
1093
app/carlink/EC/src/carlink_ec_no_lwip.c
Normal file
837
app/carlink/EY/carlink_ey.c
Normal file
@ -0,0 +1,837 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "mfcapi.h"
|
||||
#include "board.h"
|
||||
#include "lcd.h"
|
||||
#include "timer.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "FreeRTOS_DHCP_Server.h"
|
||||
#include "carlink_video.h"
|
||||
#include "carlink_ey_audio.h"
|
||||
#include "carlink_ey.h"
|
||||
#include "console.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "carlink_utils.h"
|
||||
|
||||
#if CARLINK_EY
|
||||
|
||||
#define EY_BT_EVENT_CONNECT 0
|
||||
#define EY_BT_EVENT_DISCONNECT 1
|
||||
#define EY_BT_EVENT_NOTIFY_PHONE_TYPE 2
|
||||
#define EY_BT_EVENT_NOTIFY_SSID 3
|
||||
#define EY_BT_EVENT_NOTIFY_PASSWD 4
|
||||
#define EY_BT_EVENT_NOTIFY_CONNECT_STATUS 5
|
||||
#define EY_BT_EVENT_NOTIFY_PHONE_AP_READY 6
|
||||
#define EY_BT_EVENT_NOTIFY_USE_TCP 7
|
||||
#define EY_BT_EVENT_BLE_CONNECT 8
|
||||
#define EY_CARLINK_EVENT_CONNECT 9
|
||||
#define EY_CARLINK_EVENT_DISCONNECT 10
|
||||
struct bt_event
|
||||
{
|
||||
int type;
|
||||
uint8_t para[32];
|
||||
};
|
||||
|
||||
static uint8_t gbt_ready = 0;
|
||||
static TaskHandle_t ey_bt_task = NULL;
|
||||
static TaskHandle_t ey_network_task = NULL;
|
||||
static QueueHandle_t ey_bt_event_queue = NULL;
|
||||
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
static const uint8_t ucDNSServerAddress[4] = {8, 8, 8, 8};
|
||||
static const uint8_t ucMACAddress[6] = {0x30, 0x4a, 0x26, 0x78, 0xfd, 0x12};
|
||||
static uint8_t ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t ap_passwd[16] = {"88888888"};
|
||||
static uint8_t gphone_type = 0;
|
||||
//static uint8_t guse_tcp = 1;
|
||||
static int gWifiOn = 0;
|
||||
//static int gWIfiConnecting = 0;
|
||||
static Socket_t gClientSocket = FREERTOS_INVALID_SOCKET, gXClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
static SemaphoreHandle_t gSocketMutex = NULL;
|
||||
|
||||
void cmd_test(const char* temp_uart_buf);
|
||||
|
||||
static void ey_reset_wifi_ap_info(const char *btmac)
|
||||
{
|
||||
sprintf((char *)ap_ssid, "AP630_%s", btmac);
|
||||
}
|
||||
|
||||
static void notify_carlink_state(int state)
|
||||
{
|
||||
struct bt_event ev = {0};
|
||||
ev.type = -1;
|
||||
|
||||
if (state == 0) {
|
||||
ev.type = EY_CARLINK_EVENT_DISCONNECT;
|
||||
} else {
|
||||
ev.type = EY_CARLINK_EVENT_CONNECT;
|
||||
}
|
||||
|
||||
if (0 != ev.type && NULL != ey_bt_event_queue) {
|
||||
xQueueSend(ey_bt_event_queue, &ev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void notify_phone_ip_addr(uint32_t ipAddr);
|
||||
static void ey_wifi_start_ap(const uint8_t* ssid, const uint8_t* passwd, int channel)
|
||||
{
|
||||
char cmd[64] = {0};
|
||||
uint32_t IPAddress = (32 << 24) | (13 << 16) | (168 << 8) | (192 << 0);
|
||||
|
||||
if (gWifiOn == 0) {
|
||||
printf("Turning on wifi ap...\r\n");
|
||||
WIFI_SetMode(eWiFiModeAP);
|
||||
gWifiOn = 1;
|
||||
//WIFI_On();
|
||||
sprintf(cmd, "wifi_ap %s %d %s", ssid, channel, passwd);
|
||||
cmd_test(cmd);
|
||||
|
||||
IPAddress = (20 << 24) | (13 << 16) | (168 << 8) | (192 << 0);
|
||||
dhcpserver_start(ucIPAddress, IPAddress, 10);
|
||||
}
|
||||
}
|
||||
|
||||
#define ucNumNetworks 12
|
||||
|
||||
static int ey_wifi_connect_remote_ap(const char* ssid, const char* passwd)
|
||||
{
|
||||
WIFINetworkParams_t xNetworkParams = {0};
|
||||
WIFIReturnCode_t xWifiStatus;
|
||||
int retry = 0;
|
||||
|
||||
WIFI_Context_init();
|
||||
|
||||
if (gWifiOn == 0) {
|
||||
WIFI_SetMode(eWiFiModeStation);
|
||||
|
||||
printf("Turning on wifi...\r\n");
|
||||
xWifiStatus = WIFI_On();
|
||||
|
||||
printf("Checking status...\r\n");
|
||||
if( xWifiStatus == eWiFiSuccess ) {
|
||||
printf("WiFi module initialized.\r\n");
|
||||
} else {
|
||||
printf("WiFi module failed to initialize.\r\n" );
|
||||
return -1;
|
||||
}
|
||||
gWifiOn = 1;
|
||||
}
|
||||
#if 0
|
||||
while (1) {
|
||||
printf("Starting scan\r\n");
|
||||
WIFIScanResult_t xScanResults[ ucNumNetworks ] = {0};
|
||||
xWifiStatus = WIFI_Scan( xScanResults, ucNumNetworks ); // Initiate scan
|
||||
|
||||
printf("Scan started\r\n");
|
||||
|
||||
// For each scan result, print out the SSID and RSSI
|
||||
if ( xWifiStatus == eWiFiSuccess ) {
|
||||
printf("Scan success\r\n");
|
||||
for ( uint8_t i=0; i < ucNumNetworks; i++ ) {
|
||||
printf("%s : %d \r\n", xScanResults[i].ucSSID, xScanResults[i].cRSSI);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
printf("Scan failed, status code: %d\n", (int)xWifiStatus);
|
||||
goto exit;
|
||||
//return -1;
|
||||
}
|
||||
vTaskDelay(200);
|
||||
}
|
||||
#endif
|
||||
memset(&xNetworkParams, 0, sizeof(xNetworkParams));
|
||||
xNetworkParams.ucSSIDLength = strlen( ssid );
|
||||
memcpy(xNetworkParams.ucSSID, ssid, xNetworkParams.ucSSIDLength);
|
||||
xNetworkParams.xPassword.xWPA.ucLength = strlen( passwd );
|
||||
memcpy(xNetworkParams.xPassword.xWPA.cPassphrase, passwd, xNetworkParams.xPassword.xWPA.ucLength);
|
||||
xNetworkParams.xSecurity = eWiFiSecurityWPA2;
|
||||
wifi_conn_retry:
|
||||
|
||||
xWifiStatus = WIFI_ConnectAP( &( xNetworkParams ) );
|
||||
|
||||
if( xWifiStatus == eWiFiSuccess ) {
|
||||
printf( "WiFi Connected to AP.\r\n" );
|
||||
} else {
|
||||
printf( "WiFi failed to connect to AP.\r\n" );
|
||||
if (retry++ < 15) {vTaskDelay(pdMS_TO_TICKS(300));
|
||||
goto wifi_conn_retry;}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if ( ipconfigUSE_DHCP_HOOK != 0 )
|
||||
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase,
|
||||
uint32_t ulIPAddress )
|
||||
{
|
||||
eDHCPCallbackAnswer_t eReturn;
|
||||
//uint32_t ulStaticIPAddress, ulStaticNetMask;
|
||||
char ip_str[20] = {0};
|
||||
//const uint8_t ucIPAddressDef[4] = {192, 168, 13, 37};
|
||||
|
||||
sprintf(ip_str, "%d.%d.%d.%d\r\n", (ulIPAddress >> 0) & 0xFF,
|
||||
(ulIPAddress >> 8) & 0xFF, (ulIPAddress >> 16) & 0xFF, (ulIPAddress >> 24) & 0xFF);
|
||||
printf("\r\n eDHCPPhase:%d ulIPAddress:%s state:%d \r\n", eDHCPPhase, ip_str, getDhcpClientState());
|
||||
if (getDhcpClientState() == 0)
|
||||
return eDHCPStopNoChanges;
|
||||
|
||||
switch( eDHCPPhase )
|
||||
{
|
||||
case eDHCPPhaseFinished:
|
||||
notify_phone_ip_addr(ulIPAddress);//FreeRTOS_GetIPAddress()
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
case eDHCPPhasePreDiscover :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
|
||||
case eDHCPPhasePreRequest :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
default :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
#endif
|
||||
static void notify_phone_ip_addr(uint32_t ipAddr)
|
||||
{
|
||||
char at_cmd[64] = {0};
|
||||
|
||||
if (!gbt_ready)
|
||||
return;
|
||||
memset(at_cmd, 0, sizeof(at_cmd));
|
||||
//uint32_t IPAddress = (32 << 24) | (13 << 16) | (168 << 8) | (192 << 0);
|
||||
sprintf(at_cmd, "AT+IPADDR=%d.%d.%d.%d\r\n", (ipAddr >> 0) & 0xFF,
|
||||
(ipAddr >> 8) & 0xFF, (ipAddr >> 16) & 0xFF, (ipAddr >> 24) & 0xFF);
|
||||
printf("at_cmd:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
}
|
||||
|
||||
static void notify_iphone_ssid_passwd()
|
||||
{
|
||||
char at_cmd[128] = {0};
|
||||
char bt_ssid_hex_str[64] = {0};
|
||||
char bt_passwd_hex_str[32] = {0};
|
||||
|
||||
if (!gbt_ready)
|
||||
return;
|
||||
|
||||
memset(at_cmd, 0, sizeof(at_cmd));
|
||||
|
||||
str2asiistr((const char *)ap_ssid, strlen((const char *)ap_ssid), bt_ssid_hex_str, 2 * strlen((const char *)ap_ssid));
|
||||
printf("bt_ssid_hex_str:%s\r\n", bt_ssid_hex_str);
|
||||
sprintf(at_cmd, "AT+GATTSET=AAA2%s\r\n", bt_ssid_hex_str);
|
||||
printf("ssid at:%s ||| \r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
|
||||
memset(at_cmd, 0, sizeof(at_cmd));
|
||||
str2asiistr((const char *)ap_passwd, strlen((const char *)ap_passwd), bt_passwd_hex_str, 2 * strlen((const char *)ap_passwd));
|
||||
sprintf(at_cmd, "AT+GATTSET=AAA3%s\r\n", bt_passwd_hex_str);
|
||||
printf("passwd at:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
}
|
||||
|
||||
static void notify_iphone_ap_connect_status(int status)
|
||||
{
|
||||
char at_cmd[128] = {0};
|
||||
char json_str[64] = {0};
|
||||
char json_hex_str[128] = {0};
|
||||
|
||||
if (!gbt_ready)
|
||||
return;
|
||||
|
||||
sprintf(json_str, "{\"fun\": \"hotspot\",\"type\": \"%d\"}", status);
|
||||
printf("\r\n%s \r\n", json_str);
|
||||
str2asiistr(json_str, strlen(json_str), json_hex_str, 2 * strlen(json_str));
|
||||
sprintf(at_cmd, "AT+GATTSET=AAA7%s\r\n", json_hex_str);
|
||||
printf("ssid at:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
}
|
||||
|
||||
static int readn(Socket_t xSocket, uint8_t * pvBuffer, size_t uxBufferLength)
|
||||
{
|
||||
int totalLen = 0, lBytes, retry_count = 0;
|
||||
|
||||
while (uxBufferLength > 0) {
|
||||
lBytes = FreeRTOS_recv( xSocket, (void *)pvBuffer, uxBufferLength, 0);
|
||||
if (lBytes < 0) {
|
||||
printf("FreeRTOS_recv err:%d\r\n", lBytes);
|
||||
totalLen = -1;
|
||||
break;
|
||||
}
|
||||
if (lBytes == 0) {
|
||||
printf("FreeRTOS_recv lBytes:%d\r\n", lBytes);
|
||||
if (retry_count++ > 1)
|
||||
break;
|
||||
}
|
||||
pvBuffer += lBytes;
|
||||
uxBufferLength -= lBytes;
|
||||
totalLen += lBytes;
|
||||
}
|
||||
return totalLen;
|
||||
}
|
||||
|
||||
|
||||
static void set_socket_win(Socket_t xSockets)
|
||||
{
|
||||
WinProperties_t xWinProperties;
|
||||
|
||||
memset(&xWinProperties, '\0', sizeof xWinProperties);
|
||||
|
||||
xWinProperties.lTxBufSize = ipconfigIPERF_TX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProperties.lTxWinSize = ipconfigIPERF_TX_WINSIZE; /* Size in units of MSS */
|
||||
xWinProperties.lRxBufSize = ipconfigIPERF_RX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProperties.lRxWinSize = ipconfigIPERF_RX_WINSIZE; /* Size in units of MSS */
|
||||
|
||||
FreeRTOS_setsockopt( xSockets, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProperties, sizeof( xWinProperties ) );
|
||||
}
|
||||
|
||||
static void ey_send_hu_info(Socket_t xSockets)
|
||||
{
|
||||
uint8_t reply[13] = {0};
|
||||
|
||||
reply[0] = 'O'; reply[1] = 'K';
|
||||
WRITE_LE16(reply + 2, get_carlink_video_width());
|
||||
WRITE_LE16(reply + 4, get_carlink_video_height());
|
||||
WRITE_LE16(reply + 6, get_carlink_video_width());
|
||||
WRITE_LE16(reply + 8, get_carlink_video_height());
|
||||
reply[10] = get_carlink_video_fps();
|
||||
WRITE_LE16(reply + 11, 2000);
|
||||
FreeRTOS_send(xSockets, reply, sizeof(reply), 0);
|
||||
}
|
||||
uint32_t gey_ts = 0;
|
||||
#define EY_DEBUG 0
|
||||
static void ey_network_task_proc(void* arg)
|
||||
{
|
||||
SocketSet_t xFD_Set;
|
||||
BaseType_t xResult;
|
||||
Socket_t xSockets = FREERTOS_INVALID_SOCKET;
|
||||
Socket_t xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
Socket_t xXSSockets = FREERTOS_INVALID_SOCKET;
|
||||
Socket_t xXSClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
static const TickType_t xNoTimeOut = pdMS_TO_TICKS( 2000 );
|
||||
struct freertos_sockaddr xAddress, xRemoteAddr;
|
||||
uint32_t xClientLength = sizeof( struct freertos_sockaddr );
|
||||
int32_t lBytes;
|
||||
uint8_t *header_ptr;
|
||||
msg_header header;
|
||||
#if EY_DEBUG
|
||||
void *h264SrcBuf = NULL;
|
||||
#endif
|
||||
uint8_t *h264SrcBufPtr = NULL;
|
||||
int32_t h264SrcSize = 0;
|
||||
int i;
|
||||
video_frame_s* frame = NULL;
|
||||
TickType_t xBlockingTime = pdMS_TO_TICKS( 2000 );uint32_t ts/*, r_ts*/;
|
||||
int cur_data_size = 0, pre_data_size = 0, retry_count;
|
||||
int err_flag = 0;
|
||||
|
||||
#if EY_DEBUG
|
||||
h264SrcBuf = pvPortMalloc(H264DEC_INBUF_SIZE);
|
||||
if(!h264SrcBuf) {
|
||||
printf("%s, h264SrcBuf pvPortMalloc failed.\n", __func__);
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
xFD_Set = FreeRTOS_CreateSocketSet();
|
||||
xSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
configASSERT( xSockets != FREERTOS_INVALID_SOCKET );
|
||||
FreeRTOS_setsockopt(xSockets, 0, FREERTOS_SO_RCVTIMEO, &xNoTimeOut, sizeof(xNoTimeOut));
|
||||
//FreeRTOS_setsockopt(xXSSockets, 0, FREERTOS_SO_REUSE_LISTEN_SOCKET, (void *)&option, sizeof(option));
|
||||
set_socket_win(xSockets);
|
||||
xAddress.sin_port = ( uint16_t ) 11111;
|
||||
xAddress.sin_port = FreeRTOS_htons( xAddress.sin_port );
|
||||
FreeRTOS_bind( xSockets, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_listen( xSockets, 1 );
|
||||
|
||||
xXSSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
configASSERT( xXSSockets != FREERTOS_INVALID_SOCKET );
|
||||
FreeRTOS_setsockopt(xXSSockets, 0, FREERTOS_SO_RCVTIMEO, &xNoTimeOut, sizeof(xNoTimeOut));
|
||||
//FreeRTOS_setsockopt(xXSSockets, 0, FREERTOS_SO_REUSE_LISTEN_SOCKET, (void *)&option, sizeof(option));
|
||||
set_socket_win(xXSSockets);
|
||||
xAddress.sin_port = ( uint16_t ) 11113;
|
||||
xAddress.sin_port = FreeRTOS_htons( xAddress.sin_port );
|
||||
FreeRTOS_bind( xXSSockets, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_listen( xXSSockets, 1 );
|
||||
|
||||
while(1) {
|
||||
if (err_flag != 0) {
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
if (FREERTOS_INVALID_SOCKET != xClientSocket) {
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
}
|
||||
if (FREERTOS_INVALID_SOCKET != xXSClientSocket) {
|
||||
FreeRTOS_FD_CLR(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_closesocket(xXSClientSocket);
|
||||
xXSClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
gClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
gXClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
notify_carlink_state(0);
|
||||
err_flag = 0;
|
||||
}
|
||||
FreeRTOS_FD_CLR(xSockets, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xSockets, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_CLR(xXSSockets, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xXSSockets, xFD_Set, eSELECT_READ);
|
||||
if (xClientSocket && xClientSocket != FREERTOS_INVALID_SOCKET) {
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
}
|
||||
if (xXSClientSocket && xXSClientSocket != FREERTOS_INVALID_SOCKET) {
|
||||
FreeRTOS_FD_CLR(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
}
|
||||
xResult = FreeRTOS_select( xFD_Set, xBlockingTime );
|
||||
if (xResult == 0) {//printf("select timeout\r\n");
|
||||
if (FREERTOS_INVALID_SOCKET != xClientSocket) {//maybe socket don't recv close info;
|
||||
if (cur_data_size == pre_data_size) {// no data recv
|
||||
printf("no data, retry count:%d\r\n", retry_count);
|
||||
if (retry_count++ >= 1) {// no data for 4s
|
||||
err_flag = 1;
|
||||
notify_carlink_state(0);
|
||||
}
|
||||
}
|
||||
pre_data_size = cur_data_size;
|
||||
}
|
||||
xBlockingTime = pdMS_TO_TICKS( 2000 );
|
||||
continue;
|
||||
}
|
||||
if (xResult < 0) {
|
||||
break;
|
||||
}
|
||||
pre_data_size = cur_data_size;
|
||||
|
||||
if (0){
|
||||
} else if(FreeRTOS_FD_ISSET ( xSockets, xFD_Set )) {
|
||||
xClientSocket = FreeRTOS_accept( xSockets, &xRemoteAddr, &xClientLength);
|
||||
if((xClientSocket != NULL) && (xClientSocket != FREERTOS_INVALID_SOCKET)) {
|
||||
char pucBuffer[32] = {0};
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_GetRemoteAddress( xClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
|
||||
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
|
||||
set_socket_win(xClientSocket);
|
||||
printf("\r\nServer 11111: Received a connection from %s:%u\r\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
|
||||
cur_data_size = 0;
|
||||
pre_data_size = 0;
|
||||
retry_count = 0;
|
||||
h264_dec_ctx_init();
|
||||
notify_carlink_state(1);
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
gClientSocket = xClientSocket;
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
}
|
||||
continue;
|
||||
} else if (FreeRTOS_FD_ISSET ( xXSSockets, xFD_Set )) {
|
||||
xXSClientSocket = FreeRTOS_accept( xXSSockets, &xRemoteAddr, &xClientLength);
|
||||
if ((xXSClientSocket != NULL) && (xXSClientSocket != FREERTOS_INVALID_SOCKET)) {
|
||||
char pucBuffer[32] = {0};
|
||||
FreeRTOS_FD_CLR(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_GetRemoteAddress( xXSClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
|
||||
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
|
||||
printf("\r\nServer 11113: Received a connection from %s:%u\r\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
|
||||
set_socket_win(xXSClientSocket);
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
gXClientSocket = xXSClientSocket;
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
}
|
||||
continue;
|
||||
} else if (FreeRTOS_FD_ISSET ( xXSClientSocket, xFD_Set )) {
|
||||
lBytes = FreeRTOS_recv( xXSClientSocket, (void*)&header, sizeof(header), 0);
|
||||
if (lBytes < 0) {
|
||||
printf("FreeRTOS_recv port 11113 err:%d\r\n", lBytes);
|
||||
err_flag = 1;
|
||||
} else {
|
||||
cur_data_size += lBytes;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
lBytes = FreeRTOS_recv( xClientSocket, (void*)&header, sizeof(header), 0);
|
||||
|
||||
if (lBytes < 0) {
|
||||
printf("FreeRTOS_recv port 11111 err:%d\r\n", lBytes);
|
||||
err_flag = 1;
|
||||
continue;
|
||||
}
|
||||
cur_data_size += lBytes;
|
||||
|
||||
if (lBytes == 0)
|
||||
continue;
|
||||
|
||||
if (!(header.sync_word[0] == 0xAA && header.sync_word[1] == 0xBB && header.sync_word[2] == 0xCC))
|
||||
continue;
|
||||
|
||||
if (header.type == 4) {
|
||||
uint16_t height, width;
|
||||
header_ptr = (uint8_t *)&header;
|
||||
for (i = 0; i < lBytes; i++) {
|
||||
printf("%02x ", header_ptr[i]);
|
||||
}printf("\r\n");
|
||||
|
||||
height = (header_ptr[12] | (header_ptr[13] << 8));
|
||||
width = (header_ptr[14] | (header_ptr[15] << 8));
|
||||
printf("#receive phone info width:%d height:%d\r\n", width, height);gey_ts = get_timer(0);//r_ts = header.ts;
|
||||
|
||||
ey_send_hu_info(xClientSocket);
|
||||
continue;
|
||||
} else if (header.type == 6) {
|
||||
printf("heart beat\r\n");
|
||||
continue;
|
||||
} else if (header.type != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
h264SrcSize = header.payload_size - 4;//skip timestamp
|
||||
if (h264SrcSize <= 0 || h264SrcSize > H264_FRAME_BUF_SIZE) {
|
||||
printf("h264 data len:%d err\r\n", h264SrcSize);
|
||||
continue;
|
||||
}
|
||||
#if EY_DEBUG
|
||||
h264SrcBufPtr = (uint8_t *)h264SrcBuf;
|
||||
#else
|
||||
get_retry:
|
||||
frame = get_h264_frame_buf();
|
||||
if (NULL == frame) {
|
||||
printf("h264 frame is empty\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
goto get_retry;
|
||||
//continue;
|
||||
}
|
||||
|
||||
h264SrcBufPtr = (uint8_t *)frame->cur;
|
||||
frame->len = h264SrcSize;
|
||||
#endif
|
||||
//ts = get_timer(0);
|
||||
//printf("Size:%05d lts:%03d rts:%06d\r\n", h264SrcSize, (ts - gey_ts) / 1000, header.ts - r_ts);
|
||||
gey_ts = ts;//r_ts = header.ts;
|
||||
lBytes = readn(xClientSocket, h264SrcBufPtr, h264SrcSize);
|
||||
if (h264SrcSize != lBytes) {
|
||||
set_h264_frame_free(frame);
|
||||
if (lBytes == -1) {
|
||||
printf("###FreeRTOS_recv port 11111 err:%d\r\n", lBytes);
|
||||
err_flag = 1;
|
||||
} else{
|
||||
cur_data_size += lBytes;
|
||||
}
|
||||
} else {
|
||||
cur_data_size += lBytes;
|
||||
notify_h264_frame_ready(&frame);
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s exit...\r\n", __func__);
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
if (FREERTOS_INVALID_SOCKET != xSockets)
|
||||
FreeRTOS_closesocket(xSockets);
|
||||
if (FREERTOS_INVALID_SOCKET != xXSSockets)
|
||||
FreeRTOS_closesocket(xXSSockets);
|
||||
if (FREERTOS_INVALID_SOCKET != xClientSocket)
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
if (FREERTOS_INVALID_SOCKET != xXSClientSocket)
|
||||
FreeRTOS_closesocket(xXSClientSocket);
|
||||
gClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
gXClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static int ey_start_network()
|
||||
{
|
||||
BaseType_t ret;
|
||||
ret = xTaskCreate(ey_network_task_proc, "ey_network", 2048, NULL, configMAX_PRIORITIES - 3, &ey_network_task);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ey_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
|
||||
if (0) {
|
||||
} else if (eWiFiEventConnected == xEventType) {// meter is sta
|
||||
notify_iphone_ap_connect_status(0);
|
||||
printf("\r\n The meter is connected to ap \r\n");
|
||||
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is disconnected from ap \r\n");
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
if (gClientSocket != FREERTOS_INVALID_SOCKET)
|
||||
FreeRTOS_SignalSocket(gClientSocket);// wake up socket recv
|
||||
if (gXClientSocket != FREERTOS_INVALID_SOCKET)
|
||||
FreeRTOS_SignalSocket(gClientSocket);
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
notify_phone_ip_addr(0);
|
||||
notify_carlink_state(0);
|
||||
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
|
||||
printf("\r\n The meter in AP is connected by sta %s \r\n", xEvent->xInfo.xAPStationConnected.ucMac);
|
||||
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
|
||||
printf("\r\n The sta %s is disconnected from the meter \r\n", xEvent->xInfo.xAPStationDisconnected.ucMac);
|
||||
//notify_phone_ip_addr(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int mmcsd_wait_sdio_ready(int32_t timeout);
|
||||
static int carlink_ey_network_init()
|
||||
{
|
||||
BaseType_t ret;
|
||||
unsigned int status;
|
||||
|
||||
gSocketMutex = xSemaphoreCreateMutex();
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, ey_wifi_event_handler);
|
||||
for (;;) {
|
||||
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress,ucDNSServerAddress, ucMACAddress);
|
||||
|
||||
ey_start_network();
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
static void carlink_ey_network_uninit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void ey_bt_callback(char * cAtStr)
|
||||
{
|
||||
char* cmd = NULL, *cmd_para = NULL;
|
||||
struct bt_event ev = {0};
|
||||
ev.type = -1;
|
||||
printf("\r\nfsc_bt_callback %s\r\n", cAtStr);
|
||||
if (0) {
|
||||
} else if (0 == strncmp(cAtStr, "+WLCONN", 7)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_PHONE_AP_READY;
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=EY_%s\r\n", (cAtStr + 6));
|
||||
ey_reset_wifi_ap_info(cAtStr + 6);
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=EY_%s\r\n", (cAtStr + 6));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
gbt_ready = 1;
|
||||
} else if (0 == strncmp(cAtStr, "+WLSSID=", 8)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_SSID;
|
||||
cmd_para = cAtStr + 8;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
|
||||
} else if (0 == strncmp(cAtStr, "+WLPASSWD=", 10)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_PASSWD;
|
||||
cmd_para = cAtStr + 10;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
|
||||
} else if (0 == strncmp(cAtStr, "+HFPSTAT=1", 10)) {
|
||||
ev.type = EY_BT_EVENT_DISCONNECT;
|
||||
} else if (0 == strncmp(cAtStr, "+HFPDEV=", 8)) {
|
||||
ev.type = EY_BT_EVENT_CONNECT;
|
||||
cmd_para = cAtStr + 8;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, 12);
|
||||
} else if (0 == strncmp(cAtStr, "+AAA5=", 6)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_PHONE_TYPE;
|
||||
cmd_para = cAtStr + 6;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
|
||||
} else if (0 == strncmp(cAtStr, "+AAA7=", 6)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_CONNECT_STATUS;
|
||||
cmd_para = cAtStr + 7;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3", 11)) {
|
||||
ev.type = EY_BT_EVENT_BLE_CONNECT;
|
||||
} else if (0 == strncmp(cAtStr, "+AAA9", 5)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_USE_TCP;
|
||||
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
|
||||
cmd = "AT+ADDR\r\n";
|
||||
console_send_atcmd(cmd, strlen(cmd));//get mac addr
|
||||
}
|
||||
|
||||
if (-1 != ev.type && NULL != ey_bt_event_queue) {
|
||||
xQueueSend(ey_bt_event_queue, &ev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void ey_bt_task_proc(void* arg)
|
||||
{
|
||||
struct bt_event ev;
|
||||
char* cmd_para = NULL;
|
||||
char at_cmd[128] = {0};
|
||||
char phone_type = -1;
|
||||
char ssid[32] = {0};
|
||||
char passwd[32] = {0};
|
||||
char bt_mac[12 + 1] = {0};
|
||||
int ret = -1;
|
||||
int carlink_ready_flag = 0;
|
||||
|
||||
for (;;) {
|
||||
memset((void*)&ev, 0, sizeof(ev));
|
||||
if (xQueueReceive(ey_bt_event_queue, &ev, portMAX_DELAY) != pdPASS) {
|
||||
printf("%s xQueueReceive err!\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
cmd_para = (char*)ev.para;
|
||||
if (0) {
|
||||
} else if (EY_BT_EVENT_NOTIFY_CONNECT_STATUS == ev.type) {
|
||||
} else if (EY_BT_EVENT_CONNECT == ev.type) {
|
||||
memcpy(bt_mac, cmd_para, 12);
|
||||
bt_mac[12] = '0';
|
||||
|
||||
} else if (EY_BT_EVENT_DISCONNECT == ev.type) {
|
||||
memset(ssid, 0, sizeof(ssid));
|
||||
memset(passwd, 0, sizeof(passwd));
|
||||
memset(bt_mac, 0, sizeof(bt_mac));
|
||||
phone_type = -1;
|
||||
notify_iphone_ssid_passwd();
|
||||
notify_phone_ip_addr(0);
|
||||
} else if (EY_BT_EVENT_NOTIFY_PHONE_TYPE == ev.type) {
|
||||
string2hex(cmd_para, strlen(cmd_para), &phone_type, 2);
|
||||
printf("\r\nphone type:%d\n", phone_type);
|
||||
if (phone_type != gphone_type) {
|
||||
gWifiOn = 0;// reboot wifi
|
||||
WIFI_Off();
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
}
|
||||
gphone_type = phone_type;
|
||||
if (0 == phone_type) {//android
|
||||
char type_str[5] = {0};
|
||||
char *tmp_buf = "-1";
|
||||
str2asiistr(tmp_buf, strlen(tmp_buf), type_str, 2 * strlen(tmp_buf));
|
||||
sprintf(at_cmd, "AT+GATTSET=AAA2%s\r\n", type_str);
|
||||
printf("\r\nat:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
} else if (1 == phone_type) {//iphone
|
||||
setDhcpClientState(0);
|
||||
vDHCPProcess(1, eInitialWait);
|
||||
xSendDHCPEvent();
|
||||
notify_iphone_ssid_passwd();
|
||||
ey_wifi_start_ap(ap_ssid, ap_passwd, 36);
|
||||
uint32_t ap_addr = (ucIPAddress[0]) | (ucIPAddress[1] << 8) | (ucIPAddress[2] << 16) | (ucIPAddress[3] << 24);
|
||||
notify_phone_ip_addr(ap_addr);
|
||||
}
|
||||
} else if (EY_BT_EVENT_NOTIFY_SSID == ev.type) {
|
||||
memcpy(ssid, cmd_para, strlen(cmd_para) + 1);
|
||||
printf("\r\nssid:%s\r\n", ssid);
|
||||
} else if (EY_BT_EVENT_NOTIFY_PASSWD == ev.type) {
|
||||
memcpy(passwd, cmd_para, strlen(cmd_para) + 1);
|
||||
printf("\r\npasswd:%s\r\n", passwd);
|
||||
} else if (EY_BT_EVENT_NOTIFY_PHONE_AP_READY == ev.type) {
|
||||
printf("\r\nssid:%s passwd:%s\r\n", ssid, passwd);
|
||||
setDhcpClientState(1);
|
||||
vDHCPProcess(1, eInitialWait);
|
||||
xSendDHCPEvent();
|
||||
notify_iphone_ap_connect_status(4);
|
||||
ret = ey_wifi_connect_remote_ap(ssid, passwd);
|
||||
if (ret == 0) {
|
||||
vDHCPProcess(1, eWaitingSendFirstDiscover);
|
||||
xSendDHCPEvent();
|
||||
}
|
||||
} else if (EY_BT_EVENT_NOTIFY_USE_TCP == ev.type) {
|
||||
} else if (EY_BT_EVENT_BLE_CONNECT == ev.type) {
|
||||
char bt_mac_hex_str[25] = {0};
|
||||
str2asiistr(bt_mac, 12, bt_mac_hex_str, 24);
|
||||
sprintf(at_cmd, "AT+GATTSEND=AAA5%s\r\n", bt_mac_hex_str);
|
||||
printf("\r\nat:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
} else if (EY_CARLINK_EVENT_CONNECT == ev.type) {
|
||||
carlink_ready_flag = 1;
|
||||
printf("EY_CARLINK_EVENT_CONNECT\r\n");
|
||||
set_carlink_display_state(1);
|
||||
#if EY_CARLINK_NOTIFY_HOOK
|
||||
carlink_ey_notify_state_hook(CARLINK_EY_READY);
|
||||
#endif
|
||||
} else if (EY_CARLINK_EVENT_DISCONNECT == ev.type) {
|
||||
if (carlink_ready_flag == 1) {
|
||||
printf("EY_CARLINK_EVENT_DISCONNECT\r\n");
|
||||
carlink_ready_flag = 0;
|
||||
set_carlink_display_state(0);
|
||||
#if EY_CARLINK_NOTIFY_HOOK
|
||||
carlink_ey_notify_state_hook(CARLINK_EY_EXIT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static int carlink_ey_bt_init()
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
ret = fsc_bt_main();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
console_register_cb(NULL, ey_bt_callback);
|
||||
|
||||
ey_bt_event_queue = xQueueCreate(1, sizeof(struct bt_event));
|
||||
ret = xTaskCreate(ey_bt_task_proc, "ey_bt", 2048, NULL, configMAX_PRIORITIES - 1, &ey_bt_task);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void carlink_ey_bt_uninit()
|
||||
{
|
||||
}
|
||||
|
||||
static void carlink_ey_init_thread(void *param)
|
||||
{
|
||||
carlink_ey_audio_init();
|
||||
carlink_ey_video_init();
|
||||
carlink_ey_network_init();
|
||||
carlink_ey_bt_init();
|
||||
//ey_wifi_start_ap(ap_ssid, ap_passwd, 36);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int carlink_ey_init()
|
||||
{
|
||||
#if 0
|
||||
int ret = -1;
|
||||
|
||||
ret = carlink_ey_audio_init();
|
||||
ret = carlink_ey_video_init();
|
||||
ret = carlink_ey_network_init();
|
||||
ret = carlink_ey_bt_init();
|
||||
//ey_wifi_start_ap(ap_ssid, ap_passwd, 36);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
//避免wifi模块异常后导致初始化接口阻塞,影响机器正常启动。
|
||||
xTaskCreate(carlink_ey_init_thread, "carlink_ey_init", 1024, NULL, 8, NULL);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void carlink_ey_uninit()
|
||||
{
|
||||
carlink_ey_bt_uninit();
|
||||
carlink_ey_network_uninit();
|
||||
}
|
||||
#else
|
||||
int carlink_ey_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void carlink_ey_uninit()
|
||||
{
|
||||
}
|
||||
#endif
|
33
app/carlink/EY/carlink_ey.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef __CARLINK_EY_H
|
||||
#define __CARLINK_EY_H
|
||||
|
||||
|
||||
typedef struct msg_header_st
|
||||
{
|
||||
uint8_t sync_word[3];
|
||||
uint8_t type;
|
||||
uint32_t dummy;
|
||||
uint32_t payload_size;
|
||||
uint32_t ts;
|
||||
}msg_header;
|
||||
|
||||
int carlink_ey_init(void);
|
||||
void carlink_ey_uninit(void);
|
||||
|
||||
void set_carlink_video_info(int w, int h, int fps);//set h264 video stream info from phone
|
||||
void set_carlink_display_info(int x, int y, int w, int h);//set carlink show area in lcd
|
||||
void set_carlink_display_state(int on); // on: 1.display carlink; 0. display native ui
|
||||
|
||||
#define EY_CARLINK_NOTIFY_HOOK 0
|
||||
typedef enum
|
||||
{
|
||||
CARLINK_EY_READY,
|
||||
CARLINK_EY_EXIT
|
||||
}CARLINK_EY_STATE;
|
||||
|
||||
#if EY_CARLINK_NOTIFY_HOOK
|
||||
void carlink_ey_notify_state_hook(CARLINK_EY_STATE state);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
39
app/carlink/EY/carlink_ey_audio.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
#include "carlink_ey_audio.h"
|
||||
|
||||
static int ey_bt_play_state_callback(BT_PLAY_STATE_E state, unsigned short samplerate, unsigned char channel)
|
||||
{
|
||||
printf("\r\ney_bt_play_state_callback state %d samplerate %d channel %d\r\n", state, samplerate, channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ey_bt_a2dp_pcm_data_callback(unsigned char* buffer, unsigned short length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ey_bt_hfp_spk_pcm_data_callback(unsigned char* buffer, unsigned short length)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int ey_bt_hfp_mic_pcm_data_callback(unsigned char* buffer, unsigned short length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int carlink_ey_audio_init()
|
||||
{
|
||||
bt_sw_cfg_t bt_sw_cfg = {0};
|
||||
|
||||
bt_sw_cfg.play_state_cb = ey_bt_play_state_callback;
|
||||
bt_sw_cfg.a2dp_cb = ey_bt_a2dp_pcm_data_callback;
|
||||
bt_sw_cfg.hfp_spk_cb = ey_bt_hfp_spk_pcm_data_callback;
|
||||
//bt_sw_cfg.hfp_mic_cb = ey_bt_hfp_mic_pcm_data_callback;
|
||||
|
||||
fsc_bt_register_pcm_interface((void*)&bt_sw_cfg);
|
||||
return 0;
|
||||
}
|
8
app/carlink/EY/carlink_ey_audio.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __CARLINK_EY_AUDIO_H
|
||||
#define __CARLINK_EY_AUDIO_H
|
||||
#include <FreeRTOS.h>
|
||||
#include "fscbt_interface.h"
|
||||
#include "fsc_bt.h"
|
||||
|
||||
int carlink_ey_audio_init();
|
||||
#endif
|
347
app/carlink/common/ark_network.c
Normal file
@ -0,0 +1,347 @@
|
||||
#include <stdio.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include "mmcsd_core.h"
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "iot_wifi.h"
|
||||
|
||||
const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
const uint8_t ucDNSServerAddress[4] = {8, 8, 8, 8};
|
||||
const uint8_t ucMACAddress[6] = {0x30, 0x4a, 0x26, 0x78, 0xfd, 0x12};
|
||||
|
||||
|
||||
#if !USE_LWIP
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "FreeRTOS_DHCP_Server.h"
|
||||
#include "iperf_task.h"
|
||||
|
||||
|
||||
|
||||
//static uint8_t ap_ssid[64] = {"ap63011"};
|
||||
//static uint8_t ap_passwd[16] = {"88888888"};
|
||||
|
||||
int vTestTCPClientSocket( void )
|
||||
{
|
||||
SocketSet_t xFD_Set = NULL;
|
||||
Socket_t xSocket = FREERTOS_INVALID_SOCKET;
|
||||
struct freertos_sockaddr xServerAddress;
|
||||
WinProperties_t xWinProps;
|
||||
BaseType_t ret;
|
||||
uint8_t wifi_data_buffer[2048] = {0};
|
||||
int xReturn = -1;
|
||||
|
||||
start_sta("AndroidAP", "12345678", 1);
|
||||
|
||||
xFD_Set = FreeRTOS_CreateSocketSet();
|
||||
if (NULL == xFD_Set) {
|
||||
return xReturn;
|
||||
}
|
||||
/* Create a TCP socket. */
|
||||
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
if( xSocket != FREERTOS_INVALID_SOCKET ) {
|
||||
printf( "Open socket failed\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
/* Set a time out so a missing reply does not cause the task to block indefinitely. */
|
||||
const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 4000 );
|
||||
const TickType_t xSendTimeOut = pdMS_TO_TICKS( 2000 );
|
||||
ret = FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||
ret = FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) );
|
||||
}
|
||||
|
||||
/* Set the window and buffer sizes. */
|
||||
xWinProps.lTxBufSize = ipconfigIPERF_TX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProps.lTxWinSize = ipconfigIPERF_TX_WINSIZE; /* Size in units of MSS */
|
||||
xWinProps.lRxBufSize = ipconfigIPERF_RX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProps.lRxWinSize = ipconfigIPERF_RX_WINSIZE; /* Size in units of MSS */
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) );
|
||||
|
||||
/* Connect to the echo server. */
|
||||
printf( "connecting to echo server....\r\n" );
|
||||
xServerAddress.sin_port = FreeRTOS_htons( 10010 );
|
||||
xServerAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 43, 1 );
|
||||
ret = FreeRTOS_connect( xSocket, &xServerAddress, sizeof( xServerAddress ) );
|
||||
if( ret != 0 ) {
|
||||
printf( "Could not connect to server %ld\r\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
ret = FreeRTOS_send( xSocket, (void*)wifi_data_buffer, sizeof wifi_data_buffer, 0 );
|
||||
if( ret < 0 ) {
|
||||
printf( "Could not send data to server %ld\r\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
while (1) {//waiting for data from server
|
||||
FreeRTOS_FD_CLR(xSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xSocket, xFD_Set, eSELECT_READ);
|
||||
ret = FreeRTOS_select( xFD_Set, portMAX_DELAY );
|
||||
if (ret < 0) {
|
||||
printf("Select failed\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if( FreeRTOS_FD_ISSET ( xSocket, xFD_Set ) ) {
|
||||
ret = FreeRTOS_recv(xSocket, wifi_data_buffer, sizeof wifi_data_buffer, 0);
|
||||
if (ret > 0) {
|
||||
printf("recv buf size:%d\r\n", ret);
|
||||
} else {
|
||||
printf("FreeRTOS_recv err:%d\r\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
xReturn = 0;
|
||||
|
||||
exit:
|
||||
/* Close this socket before looping back to create another. */
|
||||
if ( xSocket != FREERTOS_INVALID_SOCKET)
|
||||
FreeRTOS_closesocket( xSocket );
|
||||
|
||||
if (NULL != xFD_Set)
|
||||
FreeRTOS_DeleteSocketSet(xFD_Set);
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
static int vTestTCPServerSocket( void )
|
||||
{
|
||||
SocketSet_t xFD_Set;
|
||||
struct freertos_sockaddr xAddress, xRemoteAddr;
|
||||
Socket_t xSockets = FREERTOS_INVALID_SOCKET, xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
socklen_t xClientLength = sizeof( xAddress );
|
||||
static const TickType_t xNoTimeOut = portMAX_DELAY;
|
||||
BaseType_t ret = -1;
|
||||
BaseType_t xResult;
|
||||
uint8_t wifi_data_buffer[2048] = {0};
|
||||
|
||||
xFD_Set = FreeRTOS_CreateSocketSet();
|
||||
xSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
configASSERT( xSockets != FREERTOS_INVALID_SOCKET );
|
||||
FreeRTOS_setsockopt( xSockets,
|
||||
0,
|
||||
FREERTOS_SO_RCVTIMEO,
|
||||
&xNoTimeOut,
|
||||
sizeof( xNoTimeOut ) );
|
||||
xAddress.sin_port = ( uint16_t ) 11111;
|
||||
xAddress.sin_port = FreeRTOS_htons( xAddress.sin_port );
|
||||
FreeRTOS_bind( xSockets, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_listen( xSockets, 1 );
|
||||
|
||||
while (1) {
|
||||
FreeRTOS_FD_CLR(xSockets, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xSockets, xFD_Set, eSELECT_READ);
|
||||
if (xClientSocket && xClientSocket != FREERTOS_INVALID_SOCKET) {
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET( xClientSocket, xFD_Set, eSELECT_READ );
|
||||
}
|
||||
|
||||
xResult = FreeRTOS_select( xFD_Set, portMAX_DELAY );
|
||||
if (xResult < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if( FreeRTOS_FD_ISSET ( xSockets, xFD_Set ) ) {
|
||||
xClientSocket = FreeRTOS_accept( xSockets, &xRemoteAddr, &xClientLength);
|
||||
if( ( xClientSocket != NULL ) && ( xClientSocket != FREERTOS_INVALID_SOCKET ) ) {
|
||||
char pucBuffer[32] = {0};
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_GetRemoteAddress( xClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
|
||||
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
|
||||
printf("Carlink: Received a connection from %s:%u\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
|
||||
}
|
||||
continue;
|
||||
} else if( FreeRTOS_FD_ISSET ( xClientSocket, xFD_Set ) ) {
|
||||
|
||||
ret = FreeRTOS_recv(xClientSocket, wifi_data_buffer, sizeof wifi_data_buffer, 0);
|
||||
if (ret > 0) {
|
||||
printf("recv buf size:%d\r\n", ret);
|
||||
} else {
|
||||
printf("FreeRTOS_recv err:%d\r\n", ret);
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FREERTOS_INVALID_SOCKET != xClientSocket)
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
if (FREERTOS_INVALID_SOCKET != xSockets)
|
||||
FreeRTOS_closesocket(xSockets);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !CARLINK_EY && !CARLINK_EC
|
||||
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, uint32_t ulIPAddress )
|
||||
{
|
||||
eDHCPCallbackAnswer_t eReturn;
|
||||
char ip_str[20] = {0};
|
||||
|
||||
sprintf(ip_str, "%d.%d.%d.%d\r\n", (ulIPAddress >> 0) & 0xFF,
|
||||
(ulIPAddress >> 8) & 0xFF, (ulIPAddress >> 16) & 0xFF, (ulIPAddress >> 24) & 0xFF);
|
||||
printf("\r\n eDHCPPhase:%d ulIPAddress:%s state:%d \r\n", eDHCPPhase, ip_str, getDhcpClientState());
|
||||
if (getDhcpClientState() == 0)
|
||||
return eDHCPStopNoChanges;
|
||||
|
||||
switch( eDHCPPhase )
|
||||
{
|
||||
case eDHCPPhaseFinished:
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
case eDHCPPhasePreDiscover :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
|
||||
case eDHCPPhasePreRequest :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
default :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
static struct netif glwip_netif[4];
|
||||
|
||||
err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
|
||||
err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
extern err_t ncm_ethernetif_init(struct netif *netif);
|
||||
#endif
|
||||
|
||||
#ifdef WIFI_SUPPORT
|
||||
void wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
//WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
}
|
||||
|
||||
static BaseType_t wifi_init()
|
||||
{
|
||||
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, wifi_event_handler);
|
||||
for (;;) {
|
||||
int status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int g_flag_init_finished = 0;
|
||||
static void ark_network_init_thread(void *param)
|
||||
{
|
||||
#ifdef WIFI_SUPPORT
|
||||
BaseType_t ret = 0;
|
||||
ret = wifi_init();
|
||||
#if !USE_LWIP
|
||||
ret = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress,ucDNSServerAddress, ucMACAddress);
|
||||
|
||||
start_ap(36, "arkn141m_ap_3ca8", "88888888", 1);
|
||||
vIPerfInstall();
|
||||
vTestTCPServerSocket();
|
||||
#else
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
//start_ap(36, "arkn141m_lwip_ap_3ca8", "88888888", 1);
|
||||
start_p2p("ark630hv100_p2p", "ark630hv100", "12345678");
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(NULL, NULL);
|
||||
netif_add(&glwip_netif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
netif_set_default(&glwip_netif[0]);
|
||||
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&glwip_netif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
|
||||
netif_set_up(&glwip_netif[0]);
|
||||
|
||||
#endif
|
||||
#elif defined(CONFIG_USB_DEVICE_CDC_NCM)
|
||||
#if !USE_LWIP
|
||||
BaseType_t ret = 0;
|
||||
ret = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress,ucDNSServerAddress, ucMACAddress);
|
||||
#else
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
//ip4_addr_t dhcp_addr_start;
|
||||
//ip4_addr_t dhcp_addr_end;
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(NULL, NULL);
|
||||
netif_add(&glwip_netif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, ncm_ethernetif_init, tcpip_input);
|
||||
netif_set_default(&glwip_netif[0]);
|
||||
|
||||
/*uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&glwip_netif[0], &dhcp_addr_start, &dhcp_addr_end);*/
|
||||
|
||||
netif_set_up(&glwip_netif[0]);
|
||||
#endif
|
||||
#endif
|
||||
g_flag_init_finished = 1;
|
||||
#ifdef WIFI_SUPPORT
|
||||
ret = ret;
|
||||
#endif
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int ark_network_init()
|
||||
{
|
||||
BaseType_t ret = 0;
|
||||
if (g_flag_init_finished)
|
||||
return 0;
|
||||
g_flag_init_finished = 0;
|
||||
ret = xTaskCreate(ark_network_init_thread, "ark_net_init", 1024, NULL, 8, NULL);
|
||||
|
||||
while(!g_flag_init_finished) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
|
8
app/carlink/common/ark_network.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __ARK_NETWORK_H
|
||||
#define __ARK_NETWORK_H
|
||||
|
||||
int ark_network_init();
|
||||
|
||||
|
||||
|
||||
#endif
|
471
app/carlink/common/carlink_bt_wifi.c
Normal file
@ -0,0 +1,471 @@
|
||||
//#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "carlink_utils.h"
|
||||
#include "console.h"
|
||||
#include "fsc_bt.h"
|
||||
#include "iap.h"
|
||||
|
||||
#if !defined(USE_LWIP) || !USE_LWIP
|
||||
#error "Carlink need lwip!"
|
||||
#endif
|
||||
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
#include "lwip/apps/lwiperf.h"
|
||||
#include "dhcp.h"
|
||||
|
||||
#include "carlink_video.h"
|
||||
#include "mycommon.h"
|
||||
#include "wifi_conf.h"
|
||||
#include "carlink_common.h"
|
||||
|
||||
static char g_cp_bt_mac[13] = {0};
|
||||
static bool g_cp_bt_mac_ready = false;
|
||||
|
||||
static uint8_t carlink_ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t carlink_ap_passwd[16] = {"88888888"};
|
||||
static uint8_t carlink_wifi_mac[32] = {0};
|
||||
|
||||
extern int wps_connect_done;
|
||||
|
||||
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
|
||||
static int lwip_tcpip_init_done_flag = 0;
|
||||
|
||||
static int g_bt_wifi_init_flag = 0;
|
||||
static pthread_mutex_t btwifiLocker =
|
||||
{
|
||||
.xIsInitialized = pdFALSE,
|
||||
.xMutex = { { 0 } },
|
||||
.xTaskOwner = NULL,
|
||||
.xAttr = { .iType = 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct netif gnetif[4];
|
||||
|
||||
extern int wifi_add_custom_ie(void *cus_ie, int ie_num);
|
||||
extern int mmcsd_wait_sdio_ready(int32_t timeout);
|
||||
|
||||
static void carlink_reset_wifi_ap_info(const char *prefex);
|
||||
static void carlink_start_wlan();
|
||||
extern err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
extern err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
|
||||
|
||||
const char *carlink_get_wifi_ssid()
|
||||
{
|
||||
return (const char *)carlink_ap_ssid;
|
||||
}
|
||||
|
||||
|
||||
const char *carlink_get_wifi_mac()
|
||||
{
|
||||
wifi_get_mac_address(carlink_wifi_mac);
|
||||
return (const char *)carlink_wifi_mac;
|
||||
}
|
||||
|
||||
const char *carlink_get_wifi_passwd()
|
||||
{
|
||||
return (const char *)carlink_ap_passwd;
|
||||
}
|
||||
|
||||
void carlink_get_ap_ip_addr(char ip[4])
|
||||
{
|
||||
memcpy((void*)ip, (void*)ucIPAddress, 4);
|
||||
}
|
||||
|
||||
|
||||
static void tcpip_init_done(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
}
|
||||
|
||||
static void carlink_lwiperf_report_cb_impl(void *arg, enum lwiperf_report_type report_type,
|
||||
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
|
||||
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
printf("lwiperf_report_cb_impl bytes:%d %d ms \r\n", bytes_transferred, ms_duration);
|
||||
}
|
||||
|
||||
int carlink_wlan_tcp_ip_is_ready()
|
||||
{
|
||||
return lwip_tcpip_init_done_flag;
|
||||
}
|
||||
|
||||
//dd3000a0400000020022020961726B6D6963726F0003064C696E75780004030102030606ffffffffffff070666fadde250c0
|
||||
static u8 carplay_vendor_ie[] = {
|
||||
0xdd, 0x30, 0x00, 0xa0, 0x40, 0x00, 0x00, 0x02, 0x00, 0x22, 0x02, 0x09, 0x61, 0x72, 0x6B, 0x6D,
|
||||
0x69, 0x63, 0x72, 0x6F, 0x00, 0x03, 0x06, 0x4C, 0x69, 0x6E, 0x75, 0x78, 0x00, 0x04, 0x03, 0x01,
|
||||
0x02, 0x03, 0x06, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x06, 0x66, 0xfa, 0xdd, 0xe2,
|
||||
0x50, 0xc0
|
||||
};
|
||||
static rtw_custom_ie_t carplay_ie[1] = {{carplay_vendor_ie, PROBE_RSP | BEACON}};
|
||||
|
||||
void carlink_carplay_add_vendor_ie()
|
||||
{
|
||||
wifi_add_custom_ie((void *)carplay_ie, 1);
|
||||
}
|
||||
|
||||
void carlink_carplay_ie_replace_bt_mac(const char* btmac_str, int btmac_str_len)
|
||||
{
|
||||
char btmac[6] = {0};
|
||||
string2hex((char *)btmac_str, btmac_str_len, btmac, 6);
|
||||
//memcpy((void*)g_link_info->btmac, (void*)btmac, 6);
|
||||
//sscanf(btmac_str, "%02x%02x%02x%02x%02x%02x", btmac[0], btmac[1], btmac[2], btmac[3], btmac[4], btmac[5]);
|
||||
carplay_vendor_ie[36] = btmac[0];
|
||||
carplay_vendor_ie[37] = btmac[1];
|
||||
carplay_vendor_ie[38] = btmac[2];
|
||||
carplay_vendor_ie[39] = btmac[3];
|
||||
carplay_vendor_ie[40] = btmac[4];
|
||||
carplay_vendor_ie[41] = btmac[5];
|
||||
//memcpy((void*)(carplay_vendor_ie + 36), (void*)btmac, 6);
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(carplay_vendor_ie); i++) {
|
||||
printf("0x%02x, ", carplay_vendor_ie[i]);
|
||||
}printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void carlink_restart_bt_wifi()
|
||||
{
|
||||
carlink_bt_close();
|
||||
netif_set_down(&gnetif[0]);
|
||||
WIFI_Off();
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
carlink_bt_open();
|
||||
start_ap(36, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd, 1);
|
||||
carlink_carplay_add_vendor_ie();
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
}
|
||||
|
||||
static void carlink_start_wlan()
|
||||
{
|
||||
char ap_prefix[5] = {0};
|
||||
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
while(!g_cp_bt_mac_ready) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
memcpy(ap_prefix, g_cp_bt_mac + 8, 4);
|
||||
carlink_reset_wifi_ap_info(ap_prefix);
|
||||
start_ap(36, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd, 1);
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(tcpip_init_done, NULL);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&gnetif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
lwiperf_start_tcp_server_default(carlink_lwiperf_report_cb_impl, NULL);
|
||||
lwip_tcpip_init_done_flag = 1;
|
||||
carlink_carplay_add_vendor_ie();
|
||||
}
|
||||
|
||||
|
||||
static void carlink_reset_wifi_ap_info(const char *prefex)
|
||||
{
|
||||
if (prefex) {
|
||||
memset(carlink_ap_ssid, 0, sizeof(carlink_ap_ssid));
|
||||
sprintf((char *)carlink_ap_ssid, "AP630_CARLINK_%s", prefex);
|
||||
}
|
||||
}
|
||||
|
||||
static void carlink_bt_callback(char * cAtStr)
|
||||
{
|
||||
char* cmd_para = NULL;
|
||||
//printf("\r\nfsc_bt_callback_ec %s %d\r\n", cAtStr, strlen(cAtStr));
|
||||
struct carlink_event ev;
|
||||
memset((void*)&ev, 0, sizeof(ev));
|
||||
ev.type = CARLINK_EVENT_NONE;
|
||||
|
||||
if (0) {
|
||||
} else if (0 == strncmp(cAtStr, "+IAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
//iap2_read_data_proc(ble_buf, data_len);
|
||||
carlink_rfcomm_data_read_hook(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+AAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
//iap2_read_data_proc(ble_buf, data_len);
|
||||
carlink_rfcomm_data_read_hook(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTDATA=", 10)) {
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=1",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_DISCONNECT\r\n",__func__ ,__LINE__);
|
||||
ev.type = CARLINK_EVENT_BT_DISCONNECT;
|
||||
ev.disable_filter = true;
|
||||
carlink_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_CONNECT\r\n",__func__ ,__LINE__);
|
||||
|
||||
ev.type = CARLINK_EVENT_BT_CONNECT;
|
||||
ev.disable_filter = true;
|
||||
carlink_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=AP630_CARLINK_%s\r\n", (cAtStr + 6 + 8));
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=AP630_CARLINK_%s\r\n", (cAtStr + 6 + 8));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memcpy(g_cp_bt_mac, (cAtStr + 6), 12);
|
||||
carlink_carplay_ie_replace_bt_mac(cAtStr + 6, 12);
|
||||
g_cp_bt_mac_ready = true;
|
||||
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
|
||||
char* cmd = "AT+ADDR\r\n";
|
||||
console_send_atcmd(cmd, strlen(cmd));//get mac addr
|
||||
} else if (0 == strncmp(cAtStr, "+NAME=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+LEADDR\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get LE addr
|
||||
} else if (0 == strncmp(cAtStr, "+LEADDR=", 6)) {
|
||||
char hexMacAddr[6] = {0};
|
||||
char m_tmp_buf[64] = {0};
|
||||
string2hex(&cAtStr[8], 12, hexMacAddr, sizeof(hexMacAddr));
|
||||
sprintf(m_tmp_buf, "AT+ADVDATA=%s\r\n", hexMacAddr);
|
||||
console_send_atcmd(m_tmp_buf, 19);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSENT=", 10)) {
|
||||
return;
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=3", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_IAP_READY;
|
||||
ev.link_type = CARPLAY_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=1", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_DISCONNECT;
|
||||
ev.link_type = CARPLAY_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+AAPSTAT=3", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_AA_RFCOMM_READY;
|
||||
ev.link_type = AUTO_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+AAPSTAT=1", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_DISCONNECT;
|
||||
ev.link_type = AUTO_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
}
|
||||
}
|
||||
|
||||
int carlink_iap_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+IAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
at_str = (uint8_t *)pvPortMalloc(cmd_len + 1);
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
vPortFree(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
int carlink_auto_rfcomm_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+AAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
if (0) {
|
||||
int i;
|
||||
printf("AAPSend: ");
|
||||
for (i = 0; i < len; i++) {
|
||||
printf("%02x ", data[i]);
|
||||
}printf("\r\n");
|
||||
}
|
||||
|
||||
at_str = (uint8_t *)pvPortMalloc(cmd_len + 1);
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
vPortFree(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
void carlink_bt_open_nolock()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=1\r\n"};
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
}
|
||||
|
||||
|
||||
void carlink_bt_open()
|
||||
{
|
||||
pthread_mutex_lock(&btwifiLocker);
|
||||
if (0 == g_bt_wifi_init_flag) {
|
||||
goto exit;
|
||||
}
|
||||
carlink_bt_open_nolock();
|
||||
exit:
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
}
|
||||
|
||||
void carlink_bt_close()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=0\r\n"};
|
||||
pthread_mutex_lock(&btwifiLocker);
|
||||
if (0 == g_bt_wifi_init_flag) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
exit:
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void carlink_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
char mac_str[32] = {0};
|
||||
char *mac = NULL;
|
||||
|
||||
if (xEvent) {
|
||||
mac = xEvent->xInfo.xAPStationConnected.ucMac;
|
||||
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
wps_connect_done = 0;
|
||||
|
||||
if (0) {
|
||||
} else if (eWiFiEventConnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is connected to ap \r\n");
|
||||
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is disconnected from ap \r\n");
|
||||
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
|
||||
printf("\r\n The meter in AP is connected by sta %s \r\n", mac_str);
|
||||
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
|
||||
printf("\r\n The sta %s is disconnected from the meter \r\n", mac_str);
|
||||
}
|
||||
}
|
||||
|
||||
static BaseType_t carlink_wifi_init()
|
||||
{
|
||||
int status;
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, carlink_wifi_event_handler);
|
||||
for (;;) {
|
||||
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void bt_set_support_carplay() // cp
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=33962\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void bt_set_support_carplay_android_auto()//auto + cp
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=50346\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
|
||||
int carlink_bt_wifi_init()
|
||||
{
|
||||
pthread_mutex_lock(&btwifiLocker);
|
||||
if (g_bt_wifi_init_flag) {
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
return 0;
|
||||
}
|
||||
//carlink_ey_video_init();
|
||||
carlink_wifi_init();
|
||||
console_register_cb(NULL, carlink_bt_callback);
|
||||
fsc_bt_main();
|
||||
//bt_set_support_carplay();
|
||||
bt_set_support_carplay_android_auto();
|
||||
carlink_bt_open_nolock();
|
||||
carlink_start_wlan();
|
||||
g_bt_wifi_init_flag = 1;
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
printf("bt wlan init is ok\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
120
app/carlink/common/carlink_common.c
Normal file
@ -0,0 +1,120 @@
|
||||
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ff_sfdisk.h"
|
||||
#include "carlink_video.h"
|
||||
#include "os_adapt.h"
|
||||
|
||||
#include "carlink_common.h"
|
||||
|
||||
static QueueHandle_t carlink_event_queue = NULL;
|
||||
static struct ICalinkEventCallbacks* gcarlink_event_cbs[8];
|
||||
static int gcarlink_event_cbs_count;
|
||||
static int g_comm_init_flag = 0;
|
||||
static pthread_mutex_t carlink_com_locker =
|
||||
{
|
||||
.xIsInitialized = pdFALSE,
|
||||
.xMutex = { { 0 } },
|
||||
.xTaskOwner = NULL,
|
||||
.xAttr = { .iType = 0 }
|
||||
};
|
||||
|
||||
|
||||
void carlink_rfcomm_data_read_hook(void* buf, int len)
|
||||
{
|
||||
struct ICalinkEventCallbacks *pcb;
|
||||
int i;
|
||||
for (i = 0; i < gcarlink_event_cbs_count; i++) {
|
||||
pcb = gcarlink_event_cbs[i];
|
||||
if (pcb && pcb->onEvent) {
|
||||
pcb->rfcomm_data_read(pcb->cb_ctx, buf, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void carlink_notify_event(struct carlink_event *ev)
|
||||
{
|
||||
if (-1 != ev->type && NULL != carlink_event_queue) {
|
||||
xQueueSend(carlink_event_queue, ev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void carlink_event_proc(void* param)
|
||||
{
|
||||
struct carlink_event ev;
|
||||
struct ICalinkEventCallbacks *pcb;
|
||||
int i;
|
||||
|
||||
(void)param;
|
||||
|
||||
if (NULL == carlink_event_queue)
|
||||
return;
|
||||
|
||||
while(1) {
|
||||
if (xQueueReceive(carlink_event_queue, &ev, portMAX_DELAY) != pdPASS) {
|
||||
printf("%s xQueueReceive err!\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < gcarlink_event_cbs_count; i++) {
|
||||
pcb = gcarlink_event_cbs[i];
|
||||
if (pcb && pcb->onEvent) {
|
||||
pcb->onEvent(pcb->cb_ctx, &ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void carlink_register_event_callbacks(const struct ICalinkEventCallbacks *pcb)
|
||||
{
|
||||
if (gcarlink_event_cbs_count < 8) {
|
||||
gcarlink_event_cbs[gcarlink_event_cbs_count++] = (struct ICalinkEventCallbacks *)pcb;
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int carlink_common_init()
|
||||
{
|
||||
FF_Disk_t *sfdisk = NULL;
|
||||
BaseType_t ret = -1;
|
||||
|
||||
pthread_mutex_lock(&carlink_com_locker);
|
||||
if (g_comm_init_flag) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
carlink_ey_video_init();
|
||||
|
||||
carlink_event_queue = xQueueCreate(1, sizeof(struct carlink_event));
|
||||
if (NULL == carlink_event_queue) {
|
||||
printf("%s:%d failed\n", __func__, __LINE__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pthread_key_system_init();
|
||||
|
||||
sfdisk = FF_SFDiskInit("/sf");
|
||||
if (!sfdisk) {
|
||||
printf("FF_SFDiskInit fail.\r\n");
|
||||
//return;
|
||||
}
|
||||
|
||||
ret = xTaskCreate(carlink_event_proc, "cl_ev_proc", 2048, NULL, configMAX_PRIORITIES / 5, NULL);
|
||||
g_comm_init_flag = 1;
|
||||
|
||||
exit:
|
||||
if (ret == -1) {
|
||||
}
|
||||
pthread_mutex_unlock(&carlink_com_locker);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
87
app/carlink/common/carlink_common.h
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef __CARLINK_COMMON_H
|
||||
#define __CARLINK_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CARLINK_CARPLAY = 0x00,
|
||||
CARLINK_CARLIFE,
|
||||
CARLINK_ANDROID_CARLIFE,
|
||||
CARLINK_ANDROID_MIRROR = 3,
|
||||
CARLINK_IOS_CARLIFE,
|
||||
CARLINK_ANDROID_AUTO = 5,
|
||||
CARLINK_ECLINK = 0x06,
|
||||
CARLINK_CARPLAY_WIRELESS,
|
||||
CARLINK_AUTO_WIRELESS
|
||||
}CARLink_TYPE;
|
||||
|
||||
|
||||
|
||||
#define CARLINK_VIDEO_WIDTH 800
|
||||
#define CARLINK_VIDEO_HEIGHT 480
|
||||
|
||||
|
||||
|
||||
enum CARLINK_EVENT_TYPE
|
||||
{
|
||||
CARLINK_EVENT_NONE = 0,
|
||||
CARLINK_EVENT_BT_CONNECT,
|
||||
CARLINK_EVENT_BT_IAP_READY,
|
||||
CARLINK_EVENT_BT_AA_RFCOMM_READY,
|
||||
CARLINK_EVENT_BT_DISCONNECT,
|
||||
CARLINK_EVENT_WIFI_DISCONNECT,
|
||||
CARLINK_EVENT_WIFI_CONNECT,
|
||||
|
||||
CARLINK_EVENT_INIT_DONE,
|
||||
CARLINK_EVENT_MSG_SESSION_CONNECT,
|
||||
CARLINK_EVENT_MSG_SESSION_STOP,
|
||||
CARLINK_EVENT_MSG_DISABLE_BT
|
||||
};
|
||||
|
||||
struct carlink_event
|
||||
{
|
||||
enum CARLINK_EVENT_TYPE type;
|
||||
CARLink_TYPE link_type;
|
||||
bool disable_filter;
|
||||
union {
|
||||
int len;
|
||||
void* data;
|
||||
uint8_t para[32];
|
||||
}u;
|
||||
};
|
||||
|
||||
struct ICalinkEventCallbacks
|
||||
{
|
||||
void (*onEvent)(void* ctx, const struct carlink_event *ev);
|
||||
void (*rfcomm_data_read)(void* ctx, const void* buf, int len);
|
||||
void* cb_ctx;
|
||||
};
|
||||
|
||||
|
||||
void carlink_notify_event(struct carlink_event *ev);
|
||||
void carlink_register_event_callbacks(const struct ICalinkEventCallbacks *pcb);
|
||||
void carlink_rfcomm_data_read_hook(void* buf, int len);
|
||||
int carlink_iap_data_write(unsigned char *data, int len);
|
||||
int carlink_auto_rfcomm_data_write(unsigned char *data, int len);
|
||||
int carlink_bt_wifi_init();
|
||||
int carlink_wlan_tcp_ip_is_ready();
|
||||
void carlink_bt_open();
|
||||
void carlink_bt_close();
|
||||
void carlink_restart_bt_wifi();
|
||||
const char *carlink_get_wifi_ssid();
|
||||
const char *carlink_get_wifi_passwd();
|
||||
const char *carlink_get_wifi_mac();
|
||||
void carlink_get_ap_ip_addr(char ip[4]);
|
||||
|
||||
|
||||
int carlink_common_init();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
128
app/carlink/common/carlink_utils.c
Normal file
@ -0,0 +1,128 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "carlink_utils.h"
|
||||
#include <FreeRTOS.h>
|
||||
|
||||
#ifndef min
|
||||
#define min(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
void hex2str(const uint8_t *input, uint16_t input_len, char *output)
|
||||
{
|
||||
char *hexEncode = "0123456789ABCDEF";
|
||||
int i = 0, j = 0;
|
||||
|
||||
for (i = 0; i < input_len; i++) {
|
||||
output[j++] = hexEncode[(input[i] >> 4) & 0xf];
|
||||
output[j++] = hexEncode[(input[i]) & 0xf];
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
#define isDigit(c) (((c) <= '9' && (c) >= '0') ? (1) : (0))
|
||||
|
||||
static uint8_t hex2dec(char hex)
|
||||
{
|
||||
if (isDigit(hex)) {
|
||||
return (hex - '0');
|
||||
}
|
||||
if (hex >= 'a' && hex <= 'f') {
|
||||
return (hex - 'a' + 10);
|
||||
}
|
||||
if (hex >= 'A' && hex <= 'F') {
|
||||
return (hex - 'A' + 10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string2hex(char *input, int input_len, char *output, int max_len)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t ch0, ch1;
|
||||
|
||||
if (input_len % 2 != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (i < input_len / 2 && i < max_len) {
|
||||
ch0 = hex2dec((char)input[2 * i]);
|
||||
ch1 = hex2dec((char)input[2 * i + 1]);
|
||||
output[i] = (ch0 << 4 | ch1);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
void str2asiistr(const char *input, int input_len, char *output, int max_len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (max_len < 2 *input_len)
|
||||
return;
|
||||
|
||||
while (i < input_len) {
|
||||
sprintf(output, "%02x", input[i]);
|
||||
output += 2;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_power_of_2(uint32_t n)
|
||||
{
|
||||
return (n != 0 && ((n & (n -1)) == 0));
|
||||
}
|
||||
|
||||
// buffer_size musb be pow of 2
|
||||
int ring_buffer_init( ring_buffer_t *ctx, int buffer_size)
|
||||
{
|
||||
void *base = NULL;
|
||||
if (ctx == NULL || !is_power_of_2(buffer_size))
|
||||
return -1;
|
||||
base = pvPortMalloc(buffer_size);
|
||||
|
||||
ctx->buffer = (uint8_t *)base;
|
||||
//ctx->end = (uint8_t *)base + buffer_size;
|
||||
ctx->size = (uint32_t) buffer_size;
|
||||
ctx->mask = (uint32_t)( buffer_size - 1 );
|
||||
ctx->read_offset = 0;
|
||||
ctx->write_offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ring_buffer_free( ring_buffer_t *ctx )
|
||||
{
|
||||
if (ctx == NULL || NULL == ctx->buffer)
|
||||
return;
|
||||
vPortFree(ctx->buffer);
|
||||
}
|
||||
|
||||
uint32_t ring_buffer_write(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
len = min(len, ctx->size - ctx->write_offset + ctx->read_offset);
|
||||
|
||||
l = min(len, ctx->size - (ctx->write_offset & (ctx->mask)));
|
||||
memcpy(ctx->buffer + (ctx->write_offset & (ctx->mask)), buffer, l);
|
||||
memcpy(ctx->buffer, buffer + l, len - l);
|
||||
ctx->write_offset += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ring_buffer_read(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
len = min(len, ctx->write_offset - ctx->read_offset);
|
||||
|
||||
l = min(len, ctx->size - (ctx->read_offset & (ctx->mask)));
|
||||
memcpy(buffer, ctx->buffer + (ctx->read_offset & (ctx->mask)), l);
|
||||
memcpy(buffer + l, ctx->buffer, len - l);
|
||||
ctx->read_offset += len;
|
||||
return len;
|
||||
}
|
||||
|
31
app/carlink/common/carlink_utils.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef __CARLINK_UTILS_H
|
||||
#define __CARLINK_UTILS_H
|
||||
|
||||
void hex2str(const uint8_t *input, uint16_t input_len, char *output);
|
||||
int string2hex(char *input, int input_len, char *output, int max_len);
|
||||
void str2asiistr(const char *input, int input_len, char *output, int max_len);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * buffer;
|
||||
//const uint8_t * end;
|
||||
uint32_t size;
|
||||
uint32_t mask;
|
||||
uint32_t read_offset;
|
||||
uint32_t write_offset;
|
||||
} ring_buffer_t;
|
||||
|
||||
int ring_buffer_init( ring_buffer_t *ctx, int buffer_size);
|
||||
void ring_buffer_free( ring_buffer_t *ctx );
|
||||
uint32_t ring_buffer_write(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len);
|
||||
uint32_t ring_buffer_read(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len);
|
||||
|
||||
/*#define ring_buffer_get_read_ptr( RING ) ( &(RING)->buffer[ (RING)->read_offset & (RING)->mask ] )
|
||||
#define ring_buffer_get_write_ptr( RING ) ( &(RING)->buffer[ (RING)->write_offset & (RING)->mask ] )
|
||||
#define ring_buffer_read_advance( RING, COUNT ) do { (RING)->read_offset += (COUNT); } while( 0 )
|
||||
#define ring_buffer_write_advance( RING, COUNT ) do { (RING)->write_offset += (COUNT); } while( 0 )
|
||||
#define ring_buffer_reset( RING ) do { (RING)->read_offset = (RING)->write_offset; } while( 0 )*/
|
||||
#define ring_buffer_get_bytes_used( RING ) ( (uint32_t)( (RING)->write_offset - (RING)->read_offset ) )
|
||||
#define ring_buffer_get_bytes_free( RING ) ( (RING)->size - ring_buffer_get_bytes_used( RING ) )
|
||||
|
||||
#endif
|
347
app/carlink/common/carlink_video.c
Normal file
@ -0,0 +1,347 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "carlink_video.h"
|
||||
#include "mfcapi.h"
|
||||
#include "lcd.h"
|
||||
#include "pxp.h"
|
||||
#include "cp15/cp15.h"
|
||||
#include "timer.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#include "os_adapt.h"
|
||||
#include "ff_stdio.h"
|
||||
|
||||
static List_t frame_free_list;
|
||||
static List_t frame_ready_list;
|
||||
static video_frame_s h264_frame_fifos[H264_FRAME_FIFO_COUNT];
|
||||
static char* h264_buf = NULL;
|
||||
static SemaphoreHandle_t frame_list_mutex = NULL;
|
||||
static TaskHandle_t dec_h264_handle;
|
||||
static QueueHandle_t h264_frame_queue;
|
||||
static uint8_t g_init_flag = 0;
|
||||
static uint8_t g_video_start = 0;
|
||||
static int g_disp_x = 0, g_disp_y = 0, g_disp_width = LCD_WIDTH, g_disp_height = LCD_HEIGHT;
|
||||
static int g_video_width = LCD_WIDTH, g_video_height = LCD_HEIGHT, g_video_fps = 30;
|
||||
static int g_hide_carlink_flag = 0;
|
||||
|
||||
void set_carlink_video_info(int w, int h, int fps)
|
||||
{
|
||||
g_video_width = w;
|
||||
g_video_height = h;
|
||||
g_video_fps = fps;
|
||||
}
|
||||
|
||||
int get_carlink_video_width()
|
||||
{
|
||||
return g_video_width;
|
||||
}
|
||||
|
||||
int get_carlink_video_height()
|
||||
{
|
||||
return g_video_height;
|
||||
}
|
||||
|
||||
int get_carlink_video_fps()
|
||||
{
|
||||
return g_video_fps;
|
||||
}
|
||||
|
||||
void set_carlink_display_info(int x, int y, int w, int h)
|
||||
{
|
||||
g_disp_x = x;
|
||||
g_disp_y = y;
|
||||
g_disp_width = w;
|
||||
g_disp_height = h;
|
||||
}
|
||||
|
||||
static void h264_frame_list_reset()
|
||||
{
|
||||
video_frame_s *buffer;
|
||||
int i;
|
||||
|
||||
buffer = (video_frame_s *)h264_frame_fifos;
|
||||
vListInitialise(&frame_free_list);
|
||||
vListInitialise(&frame_ready_list);
|
||||
for(i = 0; i < H264_FRAME_FIFO_COUNT; i++) {
|
||||
buffer->buf = (char *)(((unsigned int)h264_buf + i * H264_FRAME_BUF_SIZE));
|
||||
buffer->cur = buffer->buf;
|
||||
buffer->frame_id = i;
|
||||
buffer->len = 0;
|
||||
vListInitialiseItem(&buffer->entry);
|
||||
vListInsertEnd(&frame_free_list, &buffer->entry);
|
||||
listSET_LIST_ITEM_OWNER(&buffer->entry, buffer);
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
static int h264_frame_buf_init(void)
|
||||
{
|
||||
h264_buf = pvPortMalloc(H264_FRAME_FIFO_COUNT * H264_FRAME_BUF_SIZE );
|
||||
if (h264_buf == NULL) {
|
||||
printf("malloc jpeg buf failed\r\n");
|
||||
return -1;
|
||||
}
|
||||
h264_frame_list_reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h264_dec_ctx_init()
|
||||
{
|
||||
g_video_start = 0;
|
||||
xQueueSend(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
void set_carlink_display_state(int on)
|
||||
{
|
||||
g_hide_carlink_flag = on;
|
||||
xQueueSend(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
void set_carlink_display_state_irq(int on)
|
||||
{
|
||||
g_hide_carlink_flag = on;
|
||||
|
||||
xQueueSendFromISR(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
video_frame_s* get_h264_frame_buf()
|
||||
{
|
||||
video_frame_s* frame = NULL;
|
||||
ListItem_t* item = NULL;
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (g_video_start && !listLIST_IS_EMPTY(&frame_free_list)) {
|
||||
frame = list_first_entry(&frame_free_list);
|
||||
item = listGET_HEAD_ENTRY(&frame_free_list);
|
||||
uxListRemove(item);
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
void notify_h264_frame_ready(video_frame_s** frame)
|
||||
{
|
||||
//ListItem_t* item = NULL;
|
||||
video_frame_s * tmp = *frame;
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (NULL != tmp) {
|
||||
vListInsertEnd(&frame_ready_list, &tmp->entry);
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
|
||||
xQueueSend(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
void set_h264_frame_free(video_frame_s* frame)
|
||||
{
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (g_video_start) {
|
||||
frame->cur = frame->buf;
|
||||
frame->len = 0;
|
||||
vListInsertEnd(&frame_free_list, &frame->entry);
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
}
|
||||
|
||||
static void h264_decode_proc(void *pvParameters)
|
||||
{
|
||||
MFCHandle *handle = NULL;
|
||||
DWLLinearMem_t inBuf;
|
||||
OutFrameBuffer outBuf = {0};
|
||||
int ret = -1, i;
|
||||
uint32_t align_width, align_height;
|
||||
uint32_t yaddr, uaddr, vaddr, dstaddr;
|
||||
video_frame_s* frame = NULL;
|
||||
uint32_t ts = get_timer(0), show_ts = 0, video_ts = 0;
|
||||
int32_t delta_ts = 0;;
|
||||
int carlink_lcd_take = 0;
|
||||
ListItem_t* item = NULL;
|
||||
//FF_FILE *fp = ff_fopen("/usb/ey.h264", "w+");
|
||||
|
||||
handle = mfc_init(RAW_STRM_TYPE_H264_NOREORDER);
|
||||
if(!handle) {
|
||||
printf("%s, mfc_init failed.\r\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
g_video_start = 1;
|
||||
while(1) {
|
||||
if (xQueueReceive(h264_frame_queue, NULL, portMAX_DELAY) != pdPASS) {
|
||||
printf("%s xQueueReceive err!\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
if (g_video_start == 0) {
|
||||
printf("dec uninit\r\n");
|
||||
if (carlink_lcd_take) {
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
vVideoDisplayBufGive();
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 1);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
carlink_lcd_take = 0;
|
||||
}
|
||||
mfc_uninit(handle);
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
h264_frame_list_reset();
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
xQueueReset(h264_frame_queue);
|
||||
handle = mfc_init(RAW_STRM_TYPE_H264_NOREORDER);
|
||||
if(!handle) {
|
||||
printf("%s, mfc_reinit failed.\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
g_video_start = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_hide_carlink_flag == 0) {
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 1);
|
||||
}
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (!listLIST_IS_EMPTY(&frame_ready_list)) {
|
||||
frame = list_first_entry(&frame_ready_list);
|
||||
item = listGET_HEAD_ENTRY(&frame_ready_list);
|
||||
uxListRemove(item);
|
||||
} else {
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
continue;
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
|
||||
memset(&outBuf, 0, sizeof(OutFrameBuffer));
|
||||
inBuf.busAddress = (u32)frame->cur;
|
||||
inBuf.virtualAddress = (u32 *)inBuf.busAddress;
|
||||
inBuf.size = frame->len;
|
||||
CP15_clean_dcache_for_dma(inBuf.busAddress, inBuf.busAddress + inBuf.size);
|
||||
ts = get_timer(0);
|
||||
//printf("start dec...\r\n");
|
||||
ret = mfc_decode(handle, &inBuf, &outBuf);
|
||||
//ret = 0;
|
||||
//if (NULL != fp)
|
||||
// ret = ff_fwrite((void*)inBuf.virtualAddress, 1, inBuf.size, fp);
|
||||
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
frame->cur = frame->buf;
|
||||
frame->len = 0;
|
||||
vListInsertEnd(&frame_free_list, &frame->entry);
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("h264 decode fail.\n");
|
||||
continue;
|
||||
}//printf("dec num:%d use:%d ms\r\n", outBuf.num, (get_timer(0) - ts) / 1000);
|
||||
//continue;
|
||||
|
||||
for(i = 0; i < outBuf.num; i++) {
|
||||
align_width = outBuf.frameWidth;
|
||||
align_height = outBuf.frameHeight;
|
||||
|
||||
if(!(align_width && align_height))
|
||||
continue;
|
||||
|
||||
yaddr = outBuf.buffer[i].yBusAddress;
|
||||
uaddr = yaddr + align_width * align_height;
|
||||
vaddr = yaddr + align_width * align_height * 5/4;
|
||||
|
||||
if (carlink_lcd_take == 0) {
|
||||
carlink_lcd_take = 1;
|
||||
xVideoDisplayBufTake(portMAX_DELAY);
|
||||
}
|
||||
if (carlink_lcd_take) {
|
||||
LcdOsdInfo info = {0};
|
||||
|
||||
if (0 == g_hide_carlink_flag)
|
||||
continue;
|
||||
|
||||
show_ts = get_timer(0);
|
||||
|
||||
info.format = LCD_OSD_FORAMT_YUV420; //set default format.
|
||||
if ((info.format == LCD_OSD_FORAMT_RGB565) || \
|
||||
(g_disp_width != g_video_width) || (g_disp_height != g_video_height)) {
|
||||
uint32_t pxp_width, pxp_height;
|
||||
int pxp_out_fmt = PXP_OUT_FMT_YUV2P420;
|
||||
|
||||
if(info.format == LCD_OSD_FORAMT_RGB565)
|
||||
pxp_out_fmt = PXP_OUT_FMT_RGB565;
|
||||
|
||||
//align_width = ((outBuf.frameWidth + 0xf) & (~0xf));
|
||||
if (outBuf.frameWidth != g_video_width)
|
||||
align_width = g_video_width;
|
||||
else
|
||||
align_width = outBuf.frameWidth ;
|
||||
if (outBuf.frameHeight != g_video_height)
|
||||
align_height = g_video_height;
|
||||
else
|
||||
align_height = outBuf.frameHeight;
|
||||
|
||||
pxp_width = g_disp_width;
|
||||
pxp_height = g_disp_height;
|
||||
dstaddr = ulVideoDisplayBufGet();
|
||||
|
||||
pxp_scaler_rotate(yaddr, uaddr, vaddr, PXP_SRC_FMT_YUV2P420, align_width, align_height,
|
||||
dstaddr, dstaddr + pxp_width * pxp_height, pxp_out_fmt, pxp_width, pxp_height, LCD_ROTATE_ANGLE);
|
||||
info.yaddr = dstaddr;
|
||||
info.uaddr = dstaddr + pxp_width * pxp_height;
|
||||
info.vaddr = 0;
|
||||
} else {
|
||||
info.yaddr = yaddr;
|
||||
info.uaddr = uaddr;
|
||||
info.vaddr = vaddr;
|
||||
}
|
||||
info.x = g_disp_x;
|
||||
info.y = g_disp_y;
|
||||
info.width = g_disp_width;
|
||||
info.height = g_disp_height;
|
||||
|
||||
if (info.format == LCD_OSD_FORAMT_YUV420)
|
||||
ark_lcd_set_osd_yuv420_mode(LCD_VIDEO_LAYER, LCD_OSD_Y_UV420);
|
||||
|
||||
if (!ark_lcd_get_osd_info_atomic_isactive(LCD_VIDEO_LAYER)) {
|
||||
ark_lcd_wait_for_vsync();
|
||||
}
|
||||
|
||||
ark_lcd_set_osd_info_atomic(LCD_VIDEO_LAYER, &info);
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 0);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
vVideoDisplayBufRender(dstaddr);
|
||||
if (outBuf.num > 1) {// for apple h264
|
||||
video_ts = (1000 / g_video_fps);
|
||||
show_ts = (get_timer(0) - show_ts) / 1000;
|
||||
delta_ts = ((int32_t)video_ts - (int32_t)show_ts) -3;
|
||||
//printf("delay %d ms\r\n", delta_ts);
|
||||
if (delta_ts > 0)
|
||||
vTaskDelay(pdMS_TO_TICKS(delta_ts));
|
||||
}
|
||||
}
|
||||
}
|
||||
//printf("all use:%d ms dec:%ld ms all ts:%ld ms\r\n", (get_timer(0) - ts) / 1000, dec_ts, (get_timer(0) - all_ts) / 1000);
|
||||
//all_ts = get_timer(0);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (NULL != handle)
|
||||
mfc_uninit(handle);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int carlink_ey_video_init()
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (g_init_flag ==1) {
|
||||
return 0;
|
||||
}
|
||||
g_init_flag = 1;
|
||||
ret = h264_frame_buf_init();
|
||||
frame_list_mutex = xSemaphoreCreateMutex();
|
||||
//h264_frame_queue = xQueueCreate(H264_FRAME_FIFO_COUNT, sizeof(uint32_t));
|
||||
h264_frame_queue = xQueueCreate(1, 0);
|
||||
ret = xTaskCreate(h264_decode_proc, "h264_decode_proc", 2048 * 4, NULL, configMAX_PRIORITIES - 3, &dec_h264_handle);
|
||||
return ret;
|
||||
}
|
99
app/carlink/common/carlink_video.h
Normal file
@ -0,0 +1,99 @@
|
||||
#ifndef __CARLINK_VIDEO_H
|
||||
#define __CARLINK_VIDEO_H
|
||||
#include <FreeRTOS.h>
|
||||
#include "board.h"
|
||||
#include "list.h"
|
||||
|
||||
#define H264DEC_INBUF_SIZE (LCD_WIDTH * LCD_HEIGHT * 2)
|
||||
#define H264DEC_DISP_COUNTS (2)
|
||||
#define H264_FRAME_FIFO_COUNT (16)
|
||||
#define H264_FRAME_BUF_SIZE (0x80000)
|
||||
|
||||
typedef struct h264_frame_s {
|
||||
char* buf;
|
||||
char* cur;
|
||||
unsigned int len;
|
||||
unsigned int frame_id;
|
||||
ListItem_t entry;
|
||||
} video_frame_s;
|
||||
|
||||
video_frame_s* get_h264_frame_buf(void);
|
||||
void notify_h264_frame_ready(video_frame_s** frame);
|
||||
void set_h264_frame_free(video_frame_s* frame);
|
||||
void h264_dec_ctx_init();
|
||||
int carlink_ey_video_init();
|
||||
int get_carlink_video_width(void);
|
||||
int get_carlink_video_height(void);
|
||||
int get_carlink_video_fps(void);
|
||||
|
||||
void set_carlink_video_info(int w, int h, int fps);//set h264 video stream info from phone
|
||||
void set_carlink_display_info(int x, int y, int w, int h);//set carlink show area in lcd
|
||||
void set_carlink_display_state(int on); // on: 1.display carlink; 0. display native ui
|
||||
|
||||
|
||||
#define WRITE_BE32(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = (val) >> 24; \
|
||||
*__ptr++ = ((val) & 0x00FF0000) >> 16; \
|
||||
*__ptr++ = ((val) & 0x0000FF00) >> 8; \
|
||||
*__ptr = ((val) & 0x000000FF); \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_BE16(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = (val) >> 8; \
|
||||
*__ptr = (val) & 0x00FF; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define READ_BE32(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = (*__ptr++) << 24; \
|
||||
(dest) |= (*__ptr++) << 16; \
|
||||
(dest) |= (*__ptr++) << 8; \
|
||||
(dest) |= *__ptr; \
|
||||
} while (0)
|
||||
|
||||
#define READ_BE16(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = (*__ptr++) << 8; \
|
||||
(dest) |= *__ptr; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_LE32(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = ((val) & 0x000000FF); \
|
||||
*__ptr++ = ((val) & 0x0000FF00) >> 8; \
|
||||
*__ptr++ = ((val) & 0x00FF0000) >> 16; \
|
||||
*__ptr = (val) >> 24; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_LE16(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = (val) & 0x00FF; \
|
||||
*__ptr = (val) >> 8; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define READ_LE32(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = *__ptr; \
|
||||
(dest) |= (*__ptr++) << 8; \
|
||||
(dest) |= (*__ptr++) << 16; \
|
||||
(dest) |= (*__ptr++) << 24; \
|
||||
} while (0)
|
||||
|
||||
#define READ_LE16(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = *__ptr; \
|
||||
(dest) |= (*__ptr++) << 8; \
|
||||
} while (0)
|
||||
#endif
|
153
app/carlink/common/mycommon.h
Normal file
@ -0,0 +1,153 @@
|
||||
#ifndef MYCOMMON_H_H
|
||||
#define MYCOMMON_H_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef CARLINK_LINK_TYPE
|
||||
#define CARLINK_LINK_TYPE
|
||||
typedef enum
|
||||
{
|
||||
CARPLAY = 0x00,
|
||||
CARLIFE,
|
||||
ANDROID_CARLIFE,
|
||||
ANDROID_MIRROR = 3,
|
||||
IOS_CARLIFE,
|
||||
ANDROID_AUTO = 5,
|
||||
ECLINK = 0x06,
|
||||
CARPLAY_WIRELESS,
|
||||
AUTO_WIRELESS
|
||||
}Link_TYPE;
|
||||
#endif
|
||||
|
||||
//general function
|
||||
typedef enum __USB_MODE
|
||||
{
|
||||
UNDEFINED = 0,
|
||||
HOST,
|
||||
PERIPHERAL,
|
||||
OTG
|
||||
}USB_MODE;
|
||||
|
||||
#define LOGV(...) printf(__VA_ARGS__); printf("\r\n");
|
||||
|
||||
struct view_area
|
||||
{
|
||||
short w;
|
||||
short h;
|
||||
short x;
|
||||
short y;
|
||||
};
|
||||
|
||||
typedef struct __carplay_cfg_info
|
||||
{
|
||||
char *iap2_name;
|
||||
char *iap2_modelIdentifier;
|
||||
char *iap2_manfacturer;
|
||||
char *iap2_serialnumber;
|
||||
char *iap2_sw_ver;
|
||||
char *iap2_hw_ver;
|
||||
char *iap2_vehicleInfo_name;
|
||||
char *iap2_product_uuid;
|
||||
char *iap2_usb_serial_num;
|
||||
|
||||
char *manfacturer;
|
||||
char *oem_icon_label;
|
||||
char *oem_icon_path;
|
||||
char *os_info;
|
||||
char *iOSVersionMin;
|
||||
char *limited_ui_elements;
|
||||
char *guuid;
|
||||
char *devid;
|
||||
char link_type;
|
||||
char btmac[6];
|
||||
bool oem_icon_visible;
|
||||
bool limited_ui;
|
||||
bool right_hand_driver;
|
||||
bool night_mode;
|
||||
bool has_knob;
|
||||
bool has_telbutton;
|
||||
bool has_mediabutton;
|
||||
bool has_proxsensor;
|
||||
bool has_EnhancedReqCarUI;
|
||||
bool has_ETCSupported;
|
||||
bool HiFiTouch;
|
||||
bool LoFiTouch;
|
||||
unsigned short usb_country_code;
|
||||
unsigned short tp_verndor_code;
|
||||
unsigned short tp_product_code;
|
||||
unsigned short tel_verndor_code;
|
||||
unsigned short tel_product_code;
|
||||
unsigned short knob_verndor_code;
|
||||
unsigned short knob_product_code;
|
||||
unsigned short proxsensor_verndor_code;
|
||||
unsigned short proxsensor_product_code;
|
||||
short width;//pixel
|
||||
short height;
|
||||
short fps;
|
||||
short screen_width_phy;//mm
|
||||
short screen_height_phy;
|
||||
|
||||
char encrypt_ic_i2c_bus_num;
|
||||
char encrypt_ic_addr;
|
||||
char usb_idx;
|
||||
char need_sw_aec;
|
||||
char aec_delay;
|
||||
bool tvout_enable;
|
||||
|
||||
bool use_remote_audio;
|
||||
char video_type;
|
||||
short icurrent;
|
||||
int duck_vol;
|
||||
|
||||
char enable_iap_carplay_sess;
|
||||
char *keychain_path_dir;
|
||||
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char* public_key;
|
||||
char* src_version;
|
||||
char ip_v4_addr[4];
|
||||
char wifi_channel;
|
||||
short net_port;
|
||||
|
||||
char carplay_net_ready;
|
||||
char disable_bonjour;
|
||||
char iap_carplay_rej;
|
||||
|
||||
bool enable_enhanced_siri;
|
||||
bool enable_single_ui;
|
||||
bool disable_carplay_audio;
|
||||
|
||||
short mfi_ic_i2c_bus_num;
|
||||
short mfi_ic_addr;
|
||||
|
||||
bool is_old_carplay_ver;
|
||||
|
||||
struct view_area area[3];
|
||||
char view_area_index;
|
||||
|
||||
}carplay_cfg_info;
|
||||
|
||||
typedef struct __auto_cfg_info
|
||||
{
|
||||
short width;//pixel
|
||||
short height;
|
||||
short fps;
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char wifi_channel;
|
||||
bool disable_carplay_audio;
|
||||
|
||||
} auto_cfg_info;
|
||||
|
||||
|
||||
extern carplay_cfg_info *g_link_info;
|
||||
extern auto_cfg_info *g_auto_link_info;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
59
app/double_pointer_halo/app.h
Normal file
@ -0,0 +1,59 @@
|
||||
//****************************************************************************
|
||||
//
|
||||
// Copyright (C) 2010 ShenZhen ExceedSpace
|
||||
//
|
||||
// Author ZhuoYongHong
|
||||
//
|
||||
// File name: app.h
|
||||
// D3<44>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD><EFBFBD>
|
||||
//
|
||||
// Revision history
|
||||
//
|
||||
// 2010.09.06 ZhuoYongHong Initial version
|
||||
//
|
||||
//****************************************************************************
|
||||
|
||||
#ifndef _XSPACE_APP_H_
|
||||
#define _XSPACE_APP_H_
|
||||
|
||||
#include <xm_user.h>
|
||||
#include <xm_base.h>
|
||||
#include <xm_key.h>
|
||||
#include <xm_assert.h>
|
||||
#include <xm_printf.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define XMTIMER_DESKTOPVIEW 1 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>)<29>µĶ<C2B5>ʱ<EFBFBD><CAB1>, <20><><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD>ָ<EFBFBD><D6B8>ˢ<EFBFBD><CBA2>
|
||||
#define XMTIMER_CIRCULAR_POINTER_VIEW 2 // <20><>״ָ<D7B4><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µĶ<C2B5>ʱ<EFBFBD><CAB1>, <20><><EFBFBD>ڻ<EFBFBD>״ָ<D7B4><D6B8>ˢ<EFBFBD><CBA2>
|
||||
#define XMTIMER_CLOCK_VIEW 3 // ʱ<>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD>µĶ<C2B5>ʱ<EFBFBD><CAB1>
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>)<29><>ͼ
|
||||
XMHWND_DECLARE(Desktop)
|
||||
|
||||
// <20><>״ָ<D7B4><D6B8><EFBFBD><EFBFBD>ͼ
|
||||
XMHWND_DECLARE(CircularPointer)
|
||||
|
||||
// ʱ<><CAB1><EFBFBD><EFBFBD>ͼ
|
||||
XMHWND_DECLARE(ClockView)
|
||||
|
||||
|
||||
|
||||
|
||||
void AppInit (void);
|
||||
void AppExit (void);
|
||||
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif /* end of __cplusplus */
|
||||
|
||||
#endif // #ifndef _XSPACE_APP_H_w
|
1324
app/double_pointer_halo/double_arial.c
Normal file
2269
app/double_pointer_halo/double_pointer_demo.c
Normal file
27
app/double_pointer_halo/double_pointer_demo.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef POINTER_DEMO_H
|
||||
#define POINTER_DEMO_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// <20><><EFBFBD>ε<EFBFBD>ͼaRGB8888
|
||||
extern unsigned int* get_halo_image(void);
|
||||
|
||||
extern unsigned short* get_bk_image(void);
|
||||
|
||||
int double_pointer_halo_draw (void);
|
||||
|
||||
int double_pointer_halo_init (int width, int height);
|
||||
|
||||
int double_pointer_halo_exit (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
204
app/double_pointer_halo/double_vg_font.c
Normal file
@ -0,0 +1,204 @@
|
||||
#include "vg_font.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef DOUBLE_POINTER_HALO
|
||||
|
||||
#define MAX_TEXT_SIZE 64 // 定义显示支持的最大的字符长度
|
||||
|
||||
static VGuint tmpGlyphIndices[MAX_TEXT_SIZE];
|
||||
static VGfloat tmpAdjustmentsX[MAX_TEXT_SIZE];
|
||||
static VGfloat tmpAdjustmentsY[MAX_TEXT_SIZE];
|
||||
|
||||
// Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
|
||||
#define FONS_UTF8_ACCEPT 0
|
||||
#define FONS_UTF8_REJECT 12
|
||||
|
||||
static unsigned int fons__decutf8(unsigned int* state, unsigned int* codep, unsigned int byte)
|
||||
{
|
||||
static const unsigned char utf8d[] = {
|
||||
// The first part of the table maps bytes to character classes that
|
||||
// to reduce the size of the transition table and create bitmasks.
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
||||
|
||||
// The second part is a transition table that maps a combination
|
||||
// of a state of the automaton and a character class to a state.
|
||||
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
|
||||
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
|
||||
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
|
||||
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
|
||||
12,36,12,12,12,12,12,12,12,12,12,12,
|
||||
};
|
||||
|
||||
unsigned int type = utf8d[byte];
|
||||
|
||||
*codep = (*state != FONS_UTF8_ACCEPT) ?
|
||||
(byte & 0x3fu) | (*codep << 6) :
|
||||
(0xff >> type) & (byte);
|
||||
|
||||
*state = utf8d[256 + *state + type];
|
||||
return *state;
|
||||
}
|
||||
|
||||
// 将UTF8的字符串转换为UTF32编码的32位整数串
|
||||
int utf8_to_utf32 (const char* str, const char* end,
|
||||
unsigned int *unicode, int size)
|
||||
{
|
||||
unsigned int utf8state = 0;
|
||||
unsigned int codepoint;
|
||||
int count = 0;
|
||||
for (; str != end; ++str)
|
||||
{
|
||||
if (fons__decutf8(&utf8state, &codepoint, *(const unsigned char*)str))
|
||||
continue;
|
||||
*unicode ++ = codepoint;
|
||||
size --;
|
||||
count ++;
|
||||
if(size <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static VGint kerningsCompare(const void* arg0, const void* arg1)
|
||||
{
|
||||
const KerningEntry* krn0 = (const KerningEntry*)arg0;
|
||||
const KerningEntry* krn1 = (const KerningEntry*)arg1;
|
||||
|
||||
return (VGint)krn0->key - (VGint)krn1->key;
|
||||
}
|
||||
|
||||
const KerningEntry* kerningFromGlyphIndices(const Font* font,
|
||||
const VGint leftGlyphIndex,
|
||||
const VGint rightGlyphIndex)
|
||||
{
|
||||
const KerningEntry krn =
|
||||
{
|
||||
((VGuint)leftGlyphIndex << 16) + (VGuint)rightGlyphIndex,
|
||||
0.0f, 0.0f
|
||||
};
|
||||
|
||||
return (const KerningEntry*)bsearch(&krn, font->kerningTable, font->kerningTableSize, sizeof(KerningEntry), kerningsCompare);
|
||||
}
|
||||
|
||||
// given a couple of character codes, return the relative kerning (NULL if kerning is zero)
|
||||
const KerningEntry* kerningFromCharCodes(const Font* font,
|
||||
const VGint leftCharCode,
|
||||
const VGint rightCharCode)
|
||||
{
|
||||
return ((leftCharCode >= 0) && (rightCharCode >= 0)) ? kerningFromGlyphIndices(font, leftCharCode, rightCharCode) : NULL;
|
||||
}
|
||||
|
||||
static void TextInfoBuild(const Font* font, const unsigned int* str, const size_t strLen)
|
||||
{
|
||||
size_t i;
|
||||
VGint leftGlyphIndex = *str;
|
||||
|
||||
// first glyph index
|
||||
for (i = 1; i < strLen; ++i)
|
||||
{
|
||||
const VGint rightGlyphIndex = str[i];
|
||||
const KerningEntry* krn = kerningFromGlyphIndices(font, leftGlyphIndex, rightGlyphIndex);
|
||||
// append glyph index
|
||||
// initialize adjustment
|
||||
tmpAdjustmentsX[i - 1] = 0.0f;
|
||||
tmpAdjustmentsY[i - 1] = 0.0f;
|
||||
// add kerning info
|
||||
if (krn != NULL)
|
||||
{
|
||||
tmpAdjustmentsX[i - 1] += krn->x;
|
||||
tmpAdjustmentsY[i - 1] += krn->y;
|
||||
}
|
||||
leftGlyphIndex = rightGlyphIndex;
|
||||
}
|
||||
// last adjustment entry
|
||||
tmpAdjustmentsX[strLen - 1] = 0.0f;
|
||||
tmpAdjustmentsY[strLen - 1] = 0.0f;
|
||||
}
|
||||
|
||||
// 计算字符串尺寸
|
||||
// str UTF8编码的字符串, 字符串每个字符的字形数据需要添加到字库文件(如arial.c), 否则计算失败
|
||||
// cx 保存字符串的逻辑宽度
|
||||
// cy 保存字符串的逻辑高度(始终为1.0)
|
||||
int vgTextSize(const Font* font, const char* str, VGfloat *cx, VGfloat *cy)
|
||||
{
|
||||
VGfloat glyphOrigin[2] = { 0.0f, 0.0f };
|
||||
size_t strLen;
|
||||
|
||||
if(font == NULL || str == NULL)
|
||||
return -1;
|
||||
strLen = strlen(str);
|
||||
if(strLen == 0)
|
||||
return -1;
|
||||
|
||||
strLen = utf8_to_utf32 (str, str + strLen, tmpGlyphIndices, MAX_TEXT_SIZE);
|
||||
|
||||
// build the sequence of glyph indices and kerning data
|
||||
TextInfoBuild(font, tmpGlyphIndices, strLen);
|
||||
// calculate the metrics of the glyph sequence
|
||||
vgSetfv(VG_GLYPH_ORIGIN, 2, glyphOrigin); // 设置开始的画笔位置, 此处为(0,0), 用于字符串宽度计算
|
||||
vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
|
||||
vgLoadIdentity();
|
||||
vgDrawGlyphs(font->openvgHandle, (VGint)strLen, tmpGlyphIndices, tmpAdjustmentsX, tmpAdjustmentsY, 0, VG_FALSE);
|
||||
vgGetfv(VG_GLYPH_ORIGIN, 2, glyphOrigin); // 获取结束的画笔位置
|
||||
*cx = glyphOrigin[0];
|
||||
*cy = 1.0; // 高度为1.0
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VGErrorCode arialFontInit(void);
|
||||
void arialFontDestroy(void);
|
||||
VGErrorCode courbdFontInit(void);
|
||||
void courbdFontDestroy(void);
|
||||
|
||||
int vgFontInit (void)
|
||||
{
|
||||
arialFontInit();
|
||||
//courbdFontInit ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vgFontExit (void)
|
||||
{
|
||||
arialFontDestroy();
|
||||
//courbdFontDestroy ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// draw a line of text
|
||||
// str UTF8编码的字符串, 字符串每个字符的字形数据需要添加到字库文件(如arial.c), 否则绘制失败
|
||||
int vgTextOut (const Font* font,
|
||||
const char* str,
|
||||
const VGbitfield paintModes)
|
||||
{
|
||||
size_t strLen;
|
||||
if(font == NULL || str == NULL)
|
||||
return -1;
|
||||
strLen = strlen(str);
|
||||
if(strLen == 0)
|
||||
return 0;
|
||||
if(strLen > MAX_TEXT_SIZE)
|
||||
strLen = MAX_TEXT_SIZE;
|
||||
|
||||
strLen = utf8_to_utf32 (str, str + strLen, tmpGlyphIndices, MAX_TEXT_SIZE);
|
||||
// build the sequence of glyph indices and kerning data
|
||||
TextInfoBuild (font, tmpGlyphIndices, strLen);
|
||||
// draw glyphs
|
||||
vgDrawGlyphs (font->openvgHandle, (VGint)strLen, tmpGlyphIndices, tmpAdjustmentsX, tmpAdjustmentsY, paintModes, VG_FALSE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
BIN
app/double_pointer_halo/image/原始设计数据/仪表切图/20210914切图/PNG2VG.exe
Normal file
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,2 @@
|
||||
直接点击PNG2VG.exe, 将与PNG2VG.exe,在同一目录下的PNG文件转换为RGB565, ARGB888格式.
|
||||
|
@ -0,0 +1 @@
|
||||
PNG2VG.exe
|
BIN
app/double_pointer_halo/image/原始设计数据/仪表切图/仪表切图0906/ABS.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 540 B |
BIN
app/double_pointer_halo/image/原始设计数据/仪表切图/仪表切图0906/Left_rear.png
Normal file
After Width: | Height: | Size: 540 B |