mirror of
https://github.com/Netflix/dial-reference.git
synced 2026-06-10 03:39:57 +00:00
Added app manager IPC interface. Updated verions to 2.1
This commit is contained in:
@@ -1,28 +1,247 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "nf_appmanager.h"
|
||||
#include "mq_ipc.h"
|
||||
#include "jsmn.h"
|
||||
#include "url_lib.h"
|
||||
|
||||
static char *defaultLaunchParam = "source_type=12";
|
||||
static char * mq_send_ch = "/fromAppManager";
|
||||
static char * mq_receive_ch = "/toAppManager";
|
||||
static char * mq_tx_msg_base = " {\"args\":\"%s\",\"message\":%d}";
|
||||
|
||||
static int s_run_id = 0;
|
||||
|
||||
typedef enum ControllerCommand {
|
||||
//-----------------------------------
|
||||
// Commands sent to AM
|
||||
//-----------------------------------
|
||||
CMD_CNT_START, // Launch the app
|
||||
CMD_CNT_HIDE, // Suspend app
|
||||
CMD_CNT_START_FROM_HIDE, // Resume app
|
||||
CMD_CNT_STOP=6, // Terminate app nicely because the user killed Netflix.
|
||||
CMD_CNT_GET_STATUS=8, // Provide status of the app
|
||||
}ControllerCommand_t;
|
||||
|
||||
typedef enum ControllerResp {
|
||||
//-----------------------------------
|
||||
// Resp sent from AM
|
||||
//-----------------------------------
|
||||
RESP_OK,
|
||||
RESP_ERR,
|
||||
}ControllerResp_t;
|
||||
|
||||
typedef enum NetflixStatus {
|
||||
//-----------------------------------
|
||||
// Netflix status
|
||||
//-----------------------------------
|
||||
STATUS_NETFLIX_RUNNING,
|
||||
STATUS_NETFLIX_HIDE1,
|
||||
STATUS_NETFLIX_HIDE2,
|
||||
STATUS_NETFLIX_STOPPED,
|
||||
}NetflixStatus_t;
|
||||
|
||||
|
||||
void errorMsg()
|
||||
{
|
||||
printf("\nIn this mode, a matching application manager must be started and listen on the appropriate IPC.\n\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
|
||||
if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&
|
||||
strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
NetflixStatus_t parse_nf_state(char* json_str, jsmntok_t* tokens, int num_tokens)
|
||||
{
|
||||
for (int i=0; i<num_tokens; i++){
|
||||
if (jsoneq(json_str, &tokens[i], "state") == 0) {
|
||||
char * tempStr = strndup(json_str+tokens[i+1].start, tokens[i+1].end - tokens[i+1].start);
|
||||
printf ("token: %s\n", tempStr);
|
||||
NetflixStatus_t status = (NetflixStatus_t) (atoi(tempStr));
|
||||
free(tempStr);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return STATUS_NETFLIX_STOPPED;
|
||||
}
|
||||
|
||||
DIALStatus get_nf_state()
|
||||
{
|
||||
//connect
|
||||
if (mq_ipc_connect(mq_send_ch, mq_receive_ch))
|
||||
exit(1);
|
||||
//send status request
|
||||
char tx_buf[64];
|
||||
snprintf(tx_buf, 64, mq_tx_msg_base, "", CMD_CNT_GET_STATUS);
|
||||
if (mq_ipc_send_timed(tx_buf, 2))
|
||||
errorMsg();
|
||||
//recieve status
|
||||
char rx_buf[512];
|
||||
if(mq_ipc_receive_timed(rx_buf, 512, 2))
|
||||
errorMsg();
|
||||
ATRACE("recieved: \n %s\n", rx_buf);
|
||||
|
||||
mq_ipc_disconnect();
|
||||
|
||||
// parse response
|
||||
jsmn_parser json_parser;
|
||||
jsmntok_t tokens[32]; /* We expect no more than 32 tokens */
|
||||
int num_tokens;
|
||||
jsmn_init(&json_parser);
|
||||
num_tokens = jsmn_parse(&json_parser, rx_buf, strlen(rx_buf), tokens, 32);
|
||||
|
||||
// get status
|
||||
NetflixStatus_t am_status = parse_nf_state(rx_buf, tokens, num_tokens);
|
||||
|
||||
switch (am_status){
|
||||
case STATUS_NETFLIX_HIDE1:
|
||||
case STATUS_NETFLIX_HIDE2:
|
||||
// hide state
|
||||
return kDIALStatusHide;
|
||||
break;
|
||||
case STATUS_NETFLIX_STOPPED:
|
||||
// stopped state
|
||||
return kDIALStatusStopped;
|
||||
break;
|
||||
case STATUS_NETFLIX_RUNNING:
|
||||
// running state
|
||||
return kDIALStatusRunning;
|
||||
break;
|
||||
default:
|
||||
// error state
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return kDIALStatusStopped;
|
||||
}
|
||||
|
||||
ControllerResp_t parse_am_status(char* buf)
|
||||
{
|
||||
jsmn_parser json_parser;
|
||||
jsmntok_t tokens[32]; /* We expect no more than 32 tokens */
|
||||
int num_tokens;
|
||||
jsmn_init(&json_parser);
|
||||
num_tokens = jsmn_parse(&json_parser, buf, strlen(buf), tokens, 32);
|
||||
|
||||
for (int i=0; i<num_tokens; i++){
|
||||
if (jsoneq(buf, &tokens[i], "state") == 0) {
|
||||
char * tempStr = strndup(buf+tokens[i+1].start, tokens[i+1].end - tokens[i+1].start);
|
||||
printf ("token: %s\n", tempStr);
|
||||
ControllerResp_t status = (ControllerResp_t) (atoi(tempStr));
|
||||
free(tempStr);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return RESP_ERR;
|
||||
}
|
||||
|
||||
/******************* public API ********************/
|
||||
DIALStatus am_netflix_start(DIALServer *ds, const char *appname,
|
||||
const char *payload, const char *additionalDataUrl,
|
||||
DIAL_run_t *run_id, void *callback_data)
|
||||
{
|
||||
printf ("it's all wired..\n");
|
||||
return kDIALStatusRunning;
|
||||
DIALStatus current_state = get_nf_state();
|
||||
ATRACE("current state: %d\n", current_state);
|
||||
|
||||
ATRACE ("start netflix via app manager..\n");
|
||||
|
||||
char tx_buf[512];
|
||||
char rx_buf[512];
|
||||
mq_ipc_connect(mq_send_ch, mq_receive_ch);
|
||||
|
||||
char sQueryParam[DIAL_MAX_PAYLOAD+DIAL_MAX_ADDITIONALURL+40];
|
||||
memset( sQueryParam, 0, sizeof(sQueryParam) );
|
||||
strcat( sQueryParam, "-Q ");
|
||||
strcat( sQueryParam, defaultLaunchParam );
|
||||
if(strlen(payload)){
|
||||
char * pUrlEncodedParams;
|
||||
pUrlEncodedParams = url_encode( payload );
|
||||
if( pUrlEncodedParams ){
|
||||
strcat( sQueryParam, "&dial=");
|
||||
strcat( sQueryParam, pUrlEncodedParams );
|
||||
free( pUrlEncodedParams );
|
||||
}
|
||||
}
|
||||
if(strlen(additionalDataUrl)){
|
||||
strcat(sQueryParam, "&");
|
||||
strcat(sQueryParam, additionalDataUrl);
|
||||
}
|
||||
|
||||
switch (current_state) {
|
||||
case kDIALStatusHide:
|
||||
// resume Netflix
|
||||
snprintf(tx_buf, 512, mq_tx_msg_base, sQueryParam, CMD_CNT_START_FROM_HIDE);
|
||||
break;
|
||||
case kDIALStatusStopped:
|
||||
// start Netflix
|
||||
s_run_id++;
|
||||
snprintf(tx_buf, 512, mq_tx_msg_base, sQueryParam, CMD_CNT_START);
|
||||
break;
|
||||
default:
|
||||
// Already running. Just get status
|
||||
snprintf(tx_buf, 512, mq_tx_msg_base, "", CMD_CNT_GET_STATUS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mq_ipc_send_timed(tx_buf, 2))
|
||||
errorMsg();
|
||||
if (mq_ipc_receive_timed(rx_buf, 512, 2))
|
||||
errorMsg();
|
||||
ATRACE("recieved: \n %s\n", rx_buf);
|
||||
|
||||
mq_ipc_disconnect();
|
||||
|
||||
return get_nf_state();
|
||||
}
|
||||
|
||||
DIALStatus am_netflix_hide(DIALServer *ds, const char *app_name,
|
||||
DIAL_run_t *run_id, void *callback_data)
|
||||
{
|
||||
return kDIALStatusHide;
|
||||
//connect
|
||||
if (mq_ipc_connect(mq_send_ch, mq_receive_ch))
|
||||
exit(1);
|
||||
//send status request
|
||||
char tx_buf[64];
|
||||
snprintf(tx_buf, 64, mq_tx_msg_base, "", CMD_CNT_HIDE);
|
||||
if (mq_ipc_send_timed(tx_buf, 2))
|
||||
errorMsg();
|
||||
//recieve status
|
||||
char rx_buf[512];
|
||||
if(mq_ipc_receive_timed(rx_buf, 512, 2))
|
||||
errorMsg();
|
||||
ATRACE("recieved: \n %s\n", rx_buf);
|
||||
mq_ipc_disconnect();
|
||||
|
||||
return get_nf_state();
|
||||
}
|
||||
|
||||
DIALStatus am_netflix_status(DIALServer *ds, const char *appname,
|
||||
DIAL_run_t run_id, int* pCanStop, void *callback_data)
|
||||
{
|
||||
return kDIALStatusStopped;
|
||||
return get_nf_state();
|
||||
}
|
||||
|
||||
void am_netflix_stop(DIALServer *ds, const char *appname, DIAL_run_t run_id,
|
||||
void *callback_data)
|
||||
{
|
||||
//connect
|
||||
if (mq_ipc_connect(mq_send_ch, mq_receive_ch))
|
||||
exit(1);
|
||||
//send status request
|
||||
char tx_buf[64];
|
||||
snprintf(tx_buf, 64, mq_tx_msg_base, "", CMD_CNT_STOP);
|
||||
if (mq_ipc_send_timed(tx_buf, 2))
|
||||
errorMsg();
|
||||
//recieve status
|
||||
char rx_buf[512];
|
||||
if(mq_ipc_receive_timed(rx_buf, 512, 2))
|
||||
errorMsg();
|
||||
ATRACE("recieved: \n %s\n", rx_buf);
|
||||
mq_ipc_disconnect();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user