| /* | 
 | *    mbtk_audio_ubus.c | 
 | * | 
 | *    MBTK audio ubus client API. | 
 | * | 
 | */ | 
 | /****************************************************************************** | 
 |  | 
 |                           EDIT HISTORY FOR FILE | 
 |  | 
 |   WHEN        WHO       WHAT,WHERE,WHY | 
 | --------    --------    ------------------------------------------------------- | 
 | 2024/3/18     LiuBin      Initial version | 
 |  | 
 | ******************************************************************************/ | 
 | #include <fcntl.h> | 
 | #include <stdint.h> | 
 | #include <limits.h> | 
 | #include <termios.h> | 
 | #include <stdarg.h> | 
 | #include <dirent.h> | 
 | #include <sys/stat.h> | 
 | #include <sys/statfs.h> | 
 | #include <sys/types.h> | 
 | #include "mbtk_log.h" | 
 | #include "mbtk_type.h" | 
 | #include <libubox/blobmsg_json.h> | 
 | #include "libubus.h" | 
 | #include "mbtk_audio_ubus.h" | 
 |  | 
 | #define AUDIO_UBUS_TIMEOUT 5000     // 3s | 
 |  | 
 | #define AUDIO_UBUS_REQUEST_NAME         "audio_if" | 
 | #define AUDIO_UBUS_VOLUME_SET           "volume_set" | 
 | #define AUDIO_UBUS_VOLUME_GET           "volume_status" | 
 | #define AUDIO_UBUS_MODE_SET             "audio_mode_set" | 
 | #define AUDIO_UBUS_PATH_ENABLE          "audio_path_enable" | 
 | #define AUDIO_UBUS_SWITCH_PCM           "switch_pcm" | 
 | #define AUDIO_UBUS_DSP_SET              "config_dspgain" | 
 | #define AUDIO_UBUS_LOOPBACK_EN          "loopback_enable" | 
 | #define AUDIO_UBUS_LOOPBACK_DIS         "loopback_disable" | 
 | #define AUDIO_UBUS_AUDIO_GAIN_SET       "audio_gain_set" | 
 | #define AUDIO_UBUS_AUDIO_REG_SET        "audio_reg_set" | 
 |  | 
 | static struct ubus_context *audio_ctx = NULL; | 
 | static uint32_t ubus_id_audio_if = 0; | 
 |  | 
 | static void ubus_complete_cb(struct ubus_request *req, int rc) | 
 | { | 
 |     if(audio_ctx == NULL) { | 
 |         LOGE("MBTK audio ubus not inited."); | 
 |         return; | 
 |     } | 
 |     if (req) | 
 |     { | 
 |         free(req); | 
 |         req = NULL; | 
 |     } | 
 |  | 
 |     LOGD("ubus_complete_cb() , rc = %d", rc); | 
 | } | 
 |  | 
 | int mbtk_audio_ubus_init() | 
 | { | 
 |     if(audio_ctx) { | 
 |         LOGE("MBTK audio ubus has inited."); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     audio_ctx = ubus_connect(NULL); | 
 | 	if (!audio_ctx) { | 
 | 		LOGE("Failed to connect to ubus."); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	int ret = ubus_lookup_id(audio_ctx, AUDIO_UBUS_REQUEST_NAME, &ubus_id_audio_if); | 
 | 	if (ret) { | 
 |         LOGE("ubus_lookup_id() fail."); | 
 | 		return ret; | 
 | 	} | 
 |     return 0; | 
 | } | 
 |  | 
 | int mbtk_audio_ubus_deinit() | 
 | { | 
 |     if(audio_ctx) { | 
 |         ubus_free(audio_ctx); | 
 |         audio_ctx = NULL; | 
 |         ubus_id_audio_if = 0; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 | /** | 
 |  * @brief      mbtk_audio_mode_set | 
 |  * | 
 |  * @details    detailed description | 
 |  * | 
 |  * @param      param | 
 |  *             "param0": UINT32 | 
 |  *             typedef enum { | 
 |  *                 AUDIO_MODE_INVALID = -2, | 
 |  *                 AUDIO_MODE_CURRENT = -1, | 
 |  *                 AUDIO_MODE_NORMAL = 0, | 
 |  *                 AUDIO_MODE_RINGTONE = 1, | 
 |  *                 AUDIO_MODE_IN_CALL = 2, | 
 |  *                 AUDIO_MODE_IN_COMMUNICATION=3, | 
 |  *                 AUDIO_MODE_IN_VT_CALL= 4, | 
 |  *                 AUDIO_MODE_CNT, | 
 |  *                 AUDIO_MODE_MAX = AUDIO_MODE_CNT-1, | 
 |  *             } audio_mode_ | 
 |  * @return     return type | 
 |  */ | 
 | int mbtk_audio_mode_set(int mode) | 
 | { | 
 |     if(audio_ctx == NULL || ubus_id_audio_if == 0) { | 
 |         LOGE("MBTK audio ubus not inited."); | 
 |         return -1; | 
 |     } | 
 |     static struct blob_buf b; | 
 |     int ret; | 
 |     blob_buf_init(&b, 0); | 
 |     blobmsg_add_u32(&b, "param0", mode); | 
 |     if((ret = ubus_invoke(audio_ctx, ubus_id_audio_if, AUDIO_UBUS_MODE_SET, b.head, NULL, NULL, AUDIO_UBUS_TIMEOUT)) != UBUS_STATUS_OK) { | 
 |         LOGE("ubus_invoke fail:%d.\n", ret); | 
 |         return -1; | 
 |     } else { | 
 |         LOGD("ubus_invoke success.\n"); | 
 |         return 0; | 
 |     } | 
 | } | 
 |  | 
 | /** | 
 |  * @brief      mbtk_audio_loopback_start | 
 |  * | 
 |  * @details    detailed description | 
 |  * | 
 |  * @param      param | 
 |  *             device: UINT32 | 
 |  *             0: earpiece | 
 |  *             1: speaker | 
 |  *             2: headset | 
 |  * @return     return type | 
 |  */ | 
 | int mbtk_audio_loopback_start(int device) | 
 | { | 
 |     int rc = 0; | 
 |     struct ubus_request *req = NULL; | 
 |  | 
 |     if(audio_ctx == NULL || ubus_id_audio_if == 0) { | 
 |         LOGE("MBTK audio ubus not inited."); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     req = (struct ubus_request *)malloc(sizeof(struct ubus_request)); | 
 |     if (req == NULL) | 
 |     { | 
 |         LOGE("leave %s: lack of memory", __FUNCTION__); | 
 |         return -1; | 
 |     } | 
 |     static struct blob_buf b; | 
 |     memset(req, 0, sizeof(struct ubus_request)); | 
 |     blob_buf_init(&b, 0); | 
 |     blobmsg_add_u32(&b, "param0", device); | 
 |     if ((rc = ubus_invoke_async(audio_ctx, | 
 |                                 ubus_id_audio_if, | 
 |                                 AUDIO_UBUS_LOOPBACK_EN, | 
 |                                 b.head, req)) != UBUS_STATUS_OK) { | 
 |         free(req); | 
 |         LOGE("ubus_invoke_async %s failed %s", AUDIO_UBUS_LOOPBACK_EN, ubus_strerror(rc)); | 
 |         return -1; | 
 |     } | 
 |     else | 
 |     { | 
 |         LOGD("ubus_invoke_async %s success", AUDIO_UBUS_LOOPBACK_EN); | 
 |         req->complete_cb = ubus_complete_cb; | 
 |         ubus_complete_request_async(audio_ctx, req); | 
 |         return 0; | 
 |     } | 
 | } | 
 |  | 
 | int mbtk_audio_loopback_stop() | 
 | { | 
 |     int rc = 0; | 
 |  | 
 |     if(audio_ctx == NULL || ubus_id_audio_if == 0) { | 
 |         LOGE("MBTK audio ubus not inited."); | 
 |         return -1; | 
 |     } | 
 |     static struct blob_buf b; | 
 |     blob_buf_init(&b, 0); | 
 |     if ((rc = ubus_invoke(audio_ctx, | 
 |                           ubus_id_audio_if, | 
 |                           AUDIO_UBUS_LOOPBACK_DIS, | 
 |                           b.head, NULL, NULL, AUDIO_UBUS_TIMEOUT)) != UBUS_STATUS_OK) | 
 |     { | 
 |         LOGE("ubus_invoke %s failed %s", AUDIO_UBUS_LOOPBACK_DIS, ubus_strerror(rc)); | 
 |         return -1; | 
 |     } | 
 |     else | 
 |     { | 
 |         LOGD("ubus_invoke %s success", AUDIO_UBUS_LOOPBACK_DIS); | 
 |         return 0; | 
 |     } | 
 | } | 
 |  | 
 | /** | 
 |  * @brief      mbtk_audio_dsp_gain_set | 
 |  * | 
 |  * @details    dsp gain set | 
 |  * | 
 |  * @param      param | 
 |  *             type: 0:tx | 
 |  *             0: tx | 
 |  *             1: rx | 
 |  *             gain: -36~12 db | 
 |  | 
 |  * @return     return  | 
 |  */ | 
 | int mbtk_audio_dsp_gain_set(int type, int gain) | 
 | { | 
 |     int rc = 0; | 
 |     struct ubus_request *req = NULL; | 
 |  | 
 |     if(audio_ctx == NULL || ubus_id_audio_if == 0) { | 
 |         LOGE("MBTK audio ubus not inited."); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     req = (struct ubus_request *)malloc(sizeof(struct ubus_request)); | 
 |     if (req == NULL) | 
 |     { | 
 |         LOGE("leave %s: lack of memory", __FUNCTION__); | 
 |         return -1; | 
 |     } | 
 |     static struct blob_buf b; | 
 |     memset(req, 0, sizeof(struct ubus_request)); | 
 |     blob_buf_init(&b, 0); | 
 |     blobmsg_add_u32(&b, "type", type); | 
 | 	blobmsg_add_u32(&b, "gain", gain); | 
 |     if ((rc = ubus_invoke_async(audio_ctx, | 
 |                                 ubus_id_audio_if, | 
 |                                 AUDIO_UBUS_DSP_SET, | 
 |                                 b.head, req)) != UBUS_STATUS_OK) { | 
 |         free(req); | 
 |         LOGE("ubus_invoke_async %s failed %s", AUDIO_UBUS_DSP_SET, ubus_strerror(rc)); | 
 |         return -1; | 
 |     } | 
 |     else | 
 |     { | 
 |         LOGD("ubus_invoke_async %s success", AUDIO_UBUS_DSP_SET); | 
 |         req->complete_cb = ubus_complete_cb; | 
 |         ubus_complete_request_async(audio_ctx, req); | 
 |         return 0; | 
 |     } | 
 | } | 
 |  |