1 /*
2  * Copyright (C) 2019 Knowles Electronics
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <sys/ioctl.h>
20 #include <errno.h>
21 #include <getopt.h>
22 #include <stdbool.h>
23 #include <limits.h>
24 #include <string.h>
25 #include <inttypes.h>
26 #include <linux/mfd/adnc/iaxxx-module.h>
27 
28 #define LOG_TAG "ia_crash_trigger_test"
29 
30 #include <log/log.h>
31 
32 #define GETOPT_HELP_CHAR (CHAR_MIN - 2)
33 
34 #define DEV_NODE "/dev/iaxxx-module-celldrv"
35 
36 #define CM4_SCRIPT_ID      0x1205
37 #define HMD_SCRIPT_ID      0x1206
38 #define DMX_SCRIPT_ID      0
39 
40 struct ia_script_mgr {
41     FILE *dev_node;
42 };
43 
44 static struct option const long_options[] =
45 {
46  {"simulate CM4 crash", no_argument, NULL, 'c'},
47  {"simulate HMD crash", no_argument, NULL, 'h'},
48  {"simulate DMX crash", no_argument, NULL, 'd'},
49  {"help", no_argument, NULL, GETOPT_HELP_CHAR},
50  {NULL, 0, NULL, 0}
51 };
52 
usage()53 void usage() {
54     fputs("\
55     USAGE -\n\
56     -------\n\
57     1) crash_trigger_test -c \n\
58     2) crash_trigger_test -h \n\
59     3) crash_trigger_test -d \n\
60     \n\
61     In the first form, simulate CM4 crash by script trigger\n\
62     In the second form, simulate HMD crash by script trigger\n\
63     In the third form, simulate DMX crash by script trigger\n\
64     ", stdout);
65 
66     fputs("\n\
67     OPTIONS - \n\
68     ---------\n\
69     -c          Simulate CM4 FW crash.\n\
70     -h          Simulate HMD FW crash.\n\
71     -d          Simulate DMX FW crash.\n\
72     ", stdout);
73 
74     exit(EXIT_FAILURE);
75 }
76 
main(int argc,char * argv[])77 int main(int argc, char *argv[]) {
78     struct ia_script_mgr * smd = NULL;
79     char use_case;
80     uint16_t script_id;
81     int g;
82     int err = 0;
83 
84     if (argc <= 1) {
85         usage();
86     }
87 
88     while ((g = getopt_long (argc, argv, "chd", long_options, NULL)) != -1) {
89         switch (g) {
90         case 'c':
91             use_case = 'c';
92         break;
93         case 'h':
94             use_case = 'h';
95         break;
96         case 'd':
97             use_case = 'd';
98         break;
99         case GETOPT_HELP_CHAR:
100         default:
101             usage();
102         break;
103         }
104     }
105 
106     smd = (struct ia_script_mgr*) malloc(sizeof(struct ia_script_mgr));
107     if (NULL == smd) {
108         ALOGE("%s: ERROR Failed to allocated memory for ia_script_mgr",
109                 __func__);
110         return -ENOMEM;
111     }
112 
113     if((smd->dev_node = fopen(DEV_NODE, "rw")) == NULL) {
114         ALOGE("%s: ERROR file %s open for write error: %s\n",
115                 __func__, DEV_NODE, strerror(errno));
116         err = -EBADFD;
117         goto out;
118     }
119 
120     if ('c' == use_case) {
121         // Trigger CM4 crash
122         script_id = CM4_SCRIPT_ID;
123     } else if ('h' == use_case) {
124         // Trigger HMD crash
125         script_id = HMD_SCRIPT_ID;
126     } else if ('d' == use_case) {
127         // Trigger DMX crash
128         script_id = DMX_SCRIPT_ID;
129     }
130     err = ioctl(fileno(smd->dev_node), SCRIPT_TRIGGER, (unsigned long) &script_id);
131     if ( 0 != err) {
132         ALOGE("%s: ERROR: SCRIPT EXECUTE failed %d(%s): script_id: %x\n", __func__, errno, strerror(errno), script_id);
133         goto out;
134     }
135     ALOGI("%s: script_id: %x SCRIPT TRIGGER success\n", __func__, script_id);
136 
137 out:
138 
139     if (smd) {
140         if (smd->dev_node) {
141             fclose(smd->dev_node);
142         }
143         free(smd);
144         smd = NULL;
145     }
146 
147     return err;
148 }
149