summaryrefslogtreecommitdiffstats
path: root/templates/base/01_setup_EULAfunc.sh
blob: 5ea29416ecd68e3e21e9b840d8454b950e987107 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
find_and_ack_eula() {
    # Handle EULA , if needed. This is a generic method to handle BSPs
    # that might (or not) come with a EULA. If a machine has a EULA, we
    # assume that its corresponding layers has conf/EULA/$MACHINE file
    # with the EULA text, which we will display to the user and request
    # for acceptance. If accepted, the variable ACCEPT_EULA_$MACHINE is
    # set to 1 in local.conf, which can later be used by the BSP.
    # If the env variable EULA_$MACHINE is set it is used by default,
    # without prompting the user.
    # FIXME: there is a potential issue if the same $MACHINE is set in more than one layer.. but we should assert that earlier
    # $1 is layer directory
    # $2 is location of EULA file relative to layer directory
    if test x"" == x"$2"; then
        EULA=$(find $1 -print | grep "conf/eula/$MACHINE" | grep -v scripts | grep -v openembedded-core || true)
    else
	EULA=$1/$2
    fi
    if [ -n "$EULA" ]; then
        # remove '-' since we are constructing a bash variable name here
        EULA_MACHINE="EULA_$(echo $MACHINE | sed 's/-//g')"
        # NOTE: indirect reference / dynamic variable
        if [ -n "${!EULA_MACHINE}" ]; then
            # the EULA_$MACHINE variable is set in the environment, so we just configure
            # ACCEPT_EULA_$MACHINE in local.conf
            EULA_ACCEPT=${!EULA_MACHINE}
        else
            # so we need to ask user if he/she accepts the EULA:
            cat <<EOF
The BSP for $MACHINE depends on packages and firmware which are covered by an 
End User License Agreement (EULA). To have the right to use these binaries
in your images, you need to read and accept the following...

The firmware package can contains several types of firmware (depending on BSP):

* bootloaders: the first stage bootloaders are proprietary for this
  board, they are included in this firmware package.
* firmware for the power management 'companion' core: on QCOM SoC some
  power management features are implemented in a companion core , called
  RPM, and not on the main CPU.
* firmware for GPU, WLAN, DSP/GPS and video codecs. These firmware are
  used by their respective linux drivers (DRM, wlan, v4l2, .. ) and are
  loaded on-demand by the main CPU onto the various cores on the SoC.
EOF

            echo
            REPLY=
            while [ -z "$REPLY" ]; do
                echo -n "Do you want to read the EULA ? (y/n) "
                read REPLY
                case "$REPLY" in
                    y|Y)
                        READ_EULA=1
                        ;;
                    n|N)
                        READ_EULA=0
                        ;;
                    *)
                        REPLY=
                        ;;
                esac
            done

            if [ "$READ_EULA" == 1 ]; then
                more -d ${EULA}
                echo
                REPLY=
                while [ -z "$REPLY" ]; do
                    echo -n "Do you accept the EULA you just read? (y/n) "
                    read REPLY
                    case "$REPLY" in
                        y|Y)
                            echo "EULA has been accepted."
                            EULA_ACCEPT=1
                            ;;
                        n|N)
                            echo "EULA has not been accepted."
                            ;;
                        *)
                            REPLY=
                            ;;
                    esac
                done
            fi
        fi
    fi
}

EULA_ACCEPT=0
n class="n">apiHandle, "PluginGetCB plugin section missing cannot call '%s'", json_object_get_string(callbackJ)); goto OnErrorExit; } int err = wrap_json_unpack(callbackJ, "{ss,ss,s?o!}", "plugin", &plugin, "function", &function, "args", &argsJ); if (err) { AFB_ApiError(apiHandle, "PluginGet missing plugin|function|[args] in %s", json_object_get_string(callbackJ)); goto OnErrorExit; } for (idx=0; ctlPlugins[idx].uid != NULL; idx++) { if (!strcasecmp (ctlPlugins[idx].uid, plugin)) break; } if (!ctlPlugins[idx].uid) { AFB_ApiError(apiHandle, "PluginGetCB no plugin with uid=%s", plugin); goto OnErrorExit; } action->exec.cb.funcname = function; action->exec.cb.callback = dlsym(ctlPlugins[idx].dlHandle, function); action->exec.cb.plugin= &ctlPlugins[idx]; if (!action->exec.cb.callback) { AFB_ApiError(apiHandle, "PluginGetCB no plugin=%s no function=%s", plugin, function); goto OnErrorExit; } return 0; OnErrorExit: return 1; } // Wrapper to Lua2c plugin command add context and delegate to LuaWrapper STATIC int DispatchOneL2c(void* luaState, char *funcname, Lua2cFunctionT callback) { #ifndef CONTROL_SUPPORT_LUA fprintf(stderr, "CTL-ONE-L2C: LUA support not selected (cf:CONTROL_SUPPORT_LUA) in config.cmake"); return 1; #else int err=Lua2cWrapper(luaState, funcname, callback); return err; #endif } STATIC int PluginLoadOne (AFB_ApiT apiHandle, CtlPluginT *ctlPlugin, json_object *pluginJ, void* handle) { json_object *lua2csJ = NULL, *pluginPathJ = NULL; const char*ldSearchPath = NULL, *basename = NULL; void *dlHandle; // plugin initialises at 1st load further init actions should be place into onload section if (!pluginJ) return 0; int err = wrap_json_unpack(pluginJ, "{ss,s?s,s?s,s?s,s?o !}", "uid", &ctlPlugin->uid, "info", &ctlPlugin->info, "ldpath", &ldSearchPath, "basename", &basename, "lua2c", &lua2csJ); if (err) { AFB_ApiError(apiHandle, "CTL-PLUGIN-LOADONE Plugin missing uid|[info]|basename|[ldpath]|[lua2c] in:\n-- %s", json_object_get_string(pluginJ)); goto OnErrorExit; } // default basename equal uid if (!basename) basename=ctlPlugin->uid; // if search path not in Json config file, then try default if (!ldSearchPath) { char path[CONTROL_MAXPATH_LEN]; memset(path, 0, sizeof(path)); const char *envpath = getenv("CONTROL_PLUGIN_PATH"); envpath ? strncat(path, envpath, strlen(envpath)): strncat(path, CONTROL_PLUGIN_PATH, strlen(CONTROL_PLUGIN_PATH)); const char *bPath = GetBindingDirPath(); strncat(path, ":", strlen(":")); strncat(path, bPath, strlen(bPath)); ldSearchPath = path; } // search for default policy config file pluginPathJ = ScanForConfig(ldSearchPath, CTL_SCAN_RECURSIVE, basename, CTL_PLUGIN_EXT); if (!pluginPathJ || json_object_array_length(pluginPathJ) == 0) { AFB_ApiError(apiHandle, "CTL-PLUGIN-LOADONE Missing plugin=%s*%s (config ldpath?) search=\n-- %s", basename, CTL_PLUGIN_EXT, ldSearchPath); goto OnErrorExit; } char *filename; char*fullpath; err = wrap_json_unpack(json_object_array_get_idx(pluginPathJ, 0), "{s:s, s:s !}", "fullpath", &fullpath, "filename", &filename); if (err) { AFB_ApiError(apiHandle, "CTL-PLUGIN-LOADONE HOOPs invalid plugin file path=\n-- %s", json_object_get_string(pluginPathJ)); goto OnErrorExit; } if (json_object_array_length(pluginPathJ) > 1) { AFB_ApiWarning(apiHandle, "CTL-PLUGIN-LOADONE plugin multiple instances in searchpath will use %s/%s", fullpath, filename); } char pluginpath[CONTROL_MAXPATH_LEN]; strncpy(pluginpath, fullpath, strlen (fullpath)+1); strncat(pluginpath, "/", strlen ("/")); strncat(pluginpath, filename, strlen (filename)); dlHandle = dlopen(pluginpath, RTLD_NOW); if (!dlHandle) { AFB_ApiError(apiHandle, "CTL-PLUGIN-LOADONE Fail to load pluginpath=%s err= %s", pluginpath, dlerror()); goto OnErrorExit; } CtlPluginMagicT *ctlPluginMagic = (CtlPluginMagicT*) dlsym(dlHandle, "CtlPluginMagic"); if (!ctlPluginMagic || ctlPluginMagic->magic != CTL_PLUGIN_MAGIC) { AFB_ApiError(apiHandle, "CTL-PLUGIN-LOADONE symbol'CtlPluginMagic' missing or != CTL_PLUGIN_MAGIC plugin=%s", pluginpath); goto OnErrorExit; } else { AFB_ApiNotice(apiHandle, "CTL-PLUGIN-LOADONE %s successfully registered", ctlPluginMagic->uid); } // store dlopen handle to enable onload action at exec time ctlPlugin->dlHandle = dlHandle; #ifndef AFB_BINDING_PREV3 // Jose hack to make verbosity visible from sharelib with API-V2 struct afb_binding_data_v2 *afbHidenData = dlsym(dlHandle, "afbBindingV2data"); if (afbHidenData) *afbHidenData = afbBindingV2data; #endif // Push lua2cWrapper @ into plugin Lua2cWrapperT *lua2cInPlug = dlsym(dlHandle, "Lua2cWrap"); #ifndef CONTROL_SUPPORT_LUA if (lua2cInPlug) *lua2cInPlug = NULL; #else // Lua2cWrapper is part of binder and not expose to dynamic link if (lua2csJ && lua2cInPlug) { *lua2cInPlug = DispatchOneL2c; int Lua2cAddOne(luaL_Reg *l2cFunc, const char* l2cName, int index) { if(ctlLua2cFunc->l2cCount) {index += ctlLua2cFunc->l2cCount+1;} char funcName[CONTROL_MAXPATH_LEN]; strncpy(funcName, "lua2c_", strlen ("lua2c_")+1); strncat(funcName, l2cName, strlen (l2cName)); Lua2cFunctionT l2cFunction = (Lua2cFunctionT) dlsym(dlHandle, funcName); if (!l2cFunction) { AFB_ApiError(apiHandle, "CTL-PLUGIN-LOADONE symbol'%s' missing err=%s", funcName, dlerror()); return 1; } l2cFunc[index].func = (void*) l2cFunction; l2cFunc[index].name = strdup(l2cName); return 0; } int count = 0, errCount = 0; luaL_Reg *l2cFunc = NULL; if(!ctlLua2cFunc) { ctlLua2cFunc = calloc(1, sizeof(CtlLua2cFuncT)); } // look on l2c command and push them to LUA if (json_object_get_type(lua2csJ) == json_type_array) { int length = json_object_array_length(lua2csJ); l2cFunc = calloc(length + ctlLua2cFunc->l2cCount + 1, sizeof (luaL_Reg)); for (count = 0; count < length; count++) { int err; const char *l2cName = json_object_get_string(json_object_array_get_idx(lua2csJ, count)); err = Lua2cAddOne(l2cFunc, l2cName, count); if (err) errCount++; } } else { l2cFunc = calloc(2 + ctlLua2cFunc->l2cCount, sizeof (luaL_Reg)); const char *l2cName = json_object_get_string(lua2csJ); errCount = Lua2cAddOne(l2cFunc, l2cName, count); count++; } if (errCount) { AFB_ApiError(apiHandle, "CTL-PLUGIN-LOADONE %d symbols not found in plugin='%s'", errCount, pluginpath); goto OnErrorExit; } int total = ctlLua2cFunc->l2cCount + count; if(ctlLua2cFunc->l2cCount) { for (int offset = ctlLua2cFunc->l2cCount; offset < total; offset++) { int index = offset - ctlLua2cFunc->l2cCount; l2cFunc[index] = ctlLua2cFunc->l2cFunc[index]; } free(ctlLua2cFunc->l2cFunc); } ctlLua2cFunc->l2cFunc = l2cFunc; ctlLua2cFunc->l2cCount = total; } #endif DispatchPluginInstallCbT ctlPluginOnload = dlsym(dlHandle, "CtlPluginOnload"); if (ctlPluginOnload) { ctlPlugin->api = apiHandle; ctlPlugin->context = (*ctlPluginOnload) (ctlPlugin, handle); } json_object_put(pluginPathJ); // No more needs for that json_object. return 0; OnErrorExit: json_object_put(pluginPathJ); // No more needs for that json_object. return 1; } PUBLIC int PluginConfig(AFB_ApiT apiHandle, CtlSectionT *section, json_object *pluginsJ) { int err=0; if (ctlPlugins) { int idx = 0; while(ctlPlugins[idx].uid != NULL) { // Jose hack to make verbosity visible from sharedlib and // be able to call verb from others api inside the binder struct afb_binding_data_v2 *afbHidenData = dlsym(ctlPlugins[idx++].dlHandle, "afbBindingV2data"); if (afbHidenData) *afbHidenData = afbBindingV2data; } return 0; } else { if (json_object_get_type(pluginsJ) == json_type_array) { int length = json_object_array_length(pluginsJ); ctlPlugins = calloc (length+1, sizeof(CtlPluginT)); for (int idx=0; idx < length; idx++) { json_object *pluginJ = json_object_array_get_idx(pluginsJ, idx); err += PluginLoadOne(apiHandle, &ctlPlugins[idx], pluginJ, section->handle); } } else { ctlPlugins = calloc (2, sizeof(CtlPluginT)); err += PluginLoadOne(apiHandle, &ctlPlugins[0], pluginsJ, section->handle); } } return err; }