4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this
11 * list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution.
14 * Neither the name of the NXP Semiconductor nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
53 static CmdMap g_cmd_map
;
54 static CmdObjCreateMap g_cmd_create_map
;
55 static string g_cmd_list_file
;
57 static map
<thread::id
, map
<string
, string
>> g_environment
;
59 int insert_env_variable(string key
, string value
)
61 g_environment
[std::this_thread::get_id()][key
] = value
;
65 string
get_env_variable(string key
)
67 return g_environment
[std::this_thread::get_id()][key
];
72 return g_environment
.erase(std::this_thread::get_id());
75 bool is_env_exist(string key
)
77 return g_environment
[std::this_thread::get_id()].find(key
) != g_environment
[std::this_thread::get_id()].end();
80 int get_string_in_square_brackets(const std::string
&cmd
, std::string
&context
);
81 int parser_cmd_list_file(shared_ptr
<DataBuffer
> pbuff
, CmdMap
*pCmdMap
= nullptr);
82 std::string
remove_square_brackets(const std::string
&cmd
);
85 void * create_object() { return new T
; }
87 typedef void * (*FN
)();
89 FN g_fn
= create_object
<int>;
99 int CmdBase::parser(char *p
)
104 if (parser_protocol(p
, pos
))
107 if (pos
< m_cmd
.size())
108 param
= get_next_param(m_cmd
, pos
);
112 while (pos
< m_cmd
.size())
114 param
= get_next_param(m_cmd
, pos
);
116 struct Param
*pp
= nullptr;
120 if (index
> m_param
.size())
122 set_last_err_string("More parameter then expected");
125 pp
= &(m_param
[index
]);
130 for (size_t i
= 0; i
< m_param
.size(); i
++)
132 string key
= string(m_param
[i
].key
);
133 if (compare_str(param
, key
, m_param
[i
].ignore_case
))
144 err
= "unknown Option";
146 set_last_err_string(err
);
150 if (pp
->type
== Param::Type::e_uint32
)
153 param
= get_next_param(m_cmd
, pos
);
154 *(uint32_t*)pp
->pData
= str_to_uint32(param
);
157 if (pp
->type
== Param::Type::e_uint64
)
160 param
= get_next_param(m_cmd
, pos
);
161 *(uint64_t*)pp
->pData
= str_to_uint64(param
);
164 if (pp
->type
== Param::Type::e_string_filename
)
167 param
= get_next_param(m_cmd
, pos
);
168 *(string
*)pp
->pData
= param
;
170 if (!check_file_exist(param
))
174 if (pp
->type
== Param::Type::e_string
)
177 param
= get_next_param(m_cmd
, pos
);
178 *(string
*)pp
->pData
= remove_quota(param
);
181 if (pp
->type
== Param::Type::e_bool
)
183 *(bool*)pp
->pData
= true;
186 if (pp
->type
== Param::Type::e_null
)
191 if (m_bCheckTotalParam
)
193 if (index
< m_param
.size())
197 str
+= m_param
[index
].Error
;
198 set_last_err_string(str
);
205 int CmdBase::parser_protocol(char *p
, size_t &pos
)
210 string prot
= get_next_param(m_cmd
, pos
, ':');
212 if (get_string_in_square_brackets(prot
, param
))
217 size_t param_pos
= 0;
218 string s
= get_next_param(param
, param_pos
);
223 timeout
= get_next_param(param
, param_pos
);
224 m_timeout
= str_to_uint32(timeout
);
229 err
= "Unknown option: ";
231 err
+= " for protocol: ";
232 err
+= remove_square_brackets(prot
);
233 set_last_err_string(err
);
243 nt
.type
= uuu_notify::NOTIFY_CMD_INFO
;
247 nt
.str
= (char*)str
.c_str();
253 int CmdList::run_all(CmdCtx
*p
, bool dry
)
255 CmdList::iterator it
;
259 nt
.type
= uuu_notify::NOTIFY_CMD_TOTAL
;
265 for (it
= begin(); it
!= end(); it
++, i
++)
269 nt
.type
= uuu_notify::NOTIFY_CMD_INDEX
;
273 nt
.type
= uuu_notify::NOTIFY_CMD_START
;
274 nt
.str
= (char *)(*it
)->get_cmd().c_str();
282 nt
.type
= uuu_notify::NOTIFY_CMD_END
;
288 if ((*it
)->get_lastcmd())
294 int CmdMap::run_all(const std::string
&protocol
, CmdCtx
*p
, bool dry_run
)
296 if (find(protocol
) == end())
300 err
.append("Unknown Protocol:");
301 err
.append(protocol
);
302 set_last_err_string(err
);
305 return at(protocol
)->run_all(p
, dry_run
);
308 string
get_next_param(const string
&cmd
, size_t &pos
, char separate
)
311 if (pos
== string::npos
)
313 if (pos
>= cmd
.size())
317 while (cmd
[pos
] == separate
&& pos
< cmd
.size())
321 size_t end
= string::npos
;
323 for (size_t s
= pos
; s
< cmd
.size(); s
++)
328 if (!quote
&& cmd
[s
] == separate
)
338 str
= cmd
.substr(pos
, end
- pos
);
344 string
remove_square_brackets(const string
&cmd
)
346 size_t sz
=cmd
.find('[');
347 return cmd
.substr(0, sz
);
350 int get_string_in_square_brackets(const string
&cmd
, string
&context
)
352 size_t start
= cmd
.find('[');
353 if (start
== string::npos
)
359 size_t end
= cmd
.find(']', start
);
360 if (end
== string::npos
)
362 set_last_err_string("missed ]");
366 context
= cmd
.substr(start
+ 1, end
- start
- 1);
370 template<typename T
, uint64_t MAX_VAL
>
371 T
str_to_uint(const std::string
&str
, bool * conversion_succeeded
)
373 if (conversion_succeeded
) *conversion_succeeded
= false;
378 if (str
.substr(0, 2).compare("0x") == 0)
385 const auto tmp_val
= std::stoull(str
, nullptr, base
);
386 if (tmp_val
<= MAX_VAL
)
388 if (conversion_succeeded
) *conversion_succeeded
= true;
389 return static_cast<T
>(tmp_val
);
391 } catch (const std::invalid_argument
&) {
392 } catch (const std::out_of_range
&) {
395 set_last_err_string("Conversion of string to unsigned failed");
400 uint16_t str_to_uint16(const string
&str
, bool * conversion_succeeded
)
402 return str_to_uint
<uint16_t, UINT16_MAX
>(str
, conversion_succeeded
);
405 uint32_t str_to_uint32(const string
&str
, bool * conversion_succeeded
)
407 return str_to_uint
<uint32_t, UINT32_MAX
>(str
, conversion_succeeded
);
410 uint64_t str_to_uint64(const string
&str
, bool * conversion_succeeded
)
412 return str_to_uint
<uint64_t, UINT64_MAX
>(str
, conversion_succeeded
);
415 template <class T
> shared_ptr
<CmdBase
> new_cmd_obj(char *p
)
417 return shared_ptr
<CmdBase
>(new T(p
));
420 CmdObjCreateMap::CmdObjCreateMap()
422 (*this)["CFG:"] = new_cmd_obj
<CfgCmd
>;
424 (*this)["SDPS:BOOT"] = new_cmd_obj
<SDPSCmd
>;
426 (*this)["SDP:DCD"] = new_cmd_obj
<SDPDcdCmd
>;
427 (*this)["SDP:JUMP"] = new_cmd_obj
<SDPJumpCmd
>;
428 (*this)["SDP:RDMEM"] = new_cmd_obj
<SDPReadMemCmd
>;
429 (*this)["SDP:WRMEM"] = new_cmd_obj
<SDPWriteMemCmd
>;
430 (*this)["SDP:WRITE"] = new_cmd_obj
<SDPWriteCmd
>;
431 (*this)["SDP:STATUS"] = new_cmd_obj
<SDPStatusCmd
>;
432 (*this)["SDP:BOOT"] = new_cmd_obj
<SDPBootCmd
>;
433 (*this)["SDP:BLOG"] = new_cmd_obj
<SDPBootlogCmd
>;
435 (*this)["SDPU:JUMP"] = new_cmd_obj
<SDPJumpCmd
>;
436 (*this)["SDPU:WRITE"] = new_cmd_obj
<SDPWriteCmd
>;
437 (*this)["SDPU:BLOG"] = new_cmd_obj
<SDPBootlogCmd
>;
439 (*this)["SDPV:JUMP"] = new_cmd_obj
<SDPJumpCmd
>;
440 (*this)["SDPV:WRITE"] = new_cmd_obj
<SDPWriteCmd
>;
441 (*this)["SDPV:BLOG"] = new_cmd_obj
<SDPBootlogCmd
>;
443 (*this)["FB:GETVAR"] = new_cmd_obj
<FBGetVar
>;
444 (*this)["FASTBOOT:GETVAR"] = new_cmd_obj
<FBGetVar
>;
445 (*this)["FB:UCMD"] = new_cmd_obj
<FBUCmd
>;
446 (*this)["FASTBOOT:UCMD"] = new_cmd_obj
<FBUCmd
>;
447 (*this)["FB:CRC"] = new_cmd_obj
<FBCRC
>;
448 (*this)["FASTBOOT:CRC"] = new_cmd_obj
<FBCRC
>;
449 (*this)["FB:WRITE"] = new_cmd_obj
<FBWrite
>;
450 (*this)["FASTBOOT:WRITE"] = new_cmd_obj
<FBWrite
>;
451 (*this)["FB:ACMD"] = new_cmd_obj
<FBACmd
>;
452 (*this)["FASTBOOT:ACMD"] = new_cmd_obj
<FBACmd
>;
453 (*this)["FB:DOWNLOAD"] = new_cmd_obj
<FBDownload
>;
454 (*this)["FASTBOOT:DOWNLOAD"] = new_cmd_obj
<FBDownload
>;
455 (*this)["FB:UPLOAD"] = new_cmd_obj
<FBUpload
>;
456 (*this)["FASTBOOT:UPLOAD"] = new_cmd_obj
<FBUpload
>;
457 (*this)["FB:FLASH"] = new_cmd_obj
<FBFlashCmd
>;
458 (*this)["FASTBOOT:FLASH"] = new_cmd_obj
<FBFlashCmd
>;
459 (*this)["FB:ERASE"] = new_cmd_obj
<FBEraseCmd
>;
460 (*this)["FASTBOOT:ERASE"] = new_cmd_obj
<FBEraseCmd
>;
461 (*this)["FB:REBOOT"] = new_cmd_obj
<FBRebootCmd
>;
462 (*this)["FASTBOOT:REBOOT"] = new_cmd_obj
<FBRebootCmd
>;
463 (*this)["FB:OEM"] = new_cmd_obj
<FBOemCmd
>;
464 (*this)["FASTBOOT:OEM"] = new_cmd_obj
<FBOemCmd
>;
465 (*this)["FB:FLASHING"] = new_cmd_obj
<FBFlashingCmd
>;
466 (*this)["FASTBOOT:FLASHING"] = new_cmd_obj
<FBFlashingCmd
>;
467 (*this)["FB:SET_ACTIVE"] = new_cmd_obj
<FBSetActiveCmd
>;
468 (*this)["FASTBOOT:SET_ACTIVE"] = new_cmd_obj
<FBSetActiveCmd
>;
469 (*this)["FB:BOOT"] = new_cmd_obj
<FBBootCmd
>;
470 (*this)["FASTBOOT:BOOT"] = new_cmd_obj
<FBBootCmd
>;
471 (*this)["FB:CONTINUE"] = new_cmd_obj
<FBContinueCmd
>;
472 (*this)["FASTBOOT:CONTINUE"] = new_cmd_obj
<FBContinueCmd
>;
474 (*this)["FB:UPDATE-SUPER"] = new_cmd_obj
<FBUpdateSuper
>;
475 (*this)["FASTBOOT:UPDATE-SUPER"] = new_cmd_obj
<FBUpdateSuper
>;
476 (*this)["FB:CREATE-LOGICAL-PARTITION"] = new_cmd_obj
<FBCreatePartition
>;
477 (*this)["FASTBOOT:CREATE-LOGICAL-PARTITION"] = new_cmd_obj
<FBCreatePartition
>;
478 (*this)["FB:DELETE-LOGICAL-PARTITION"] = new_cmd_obj
<FBDelPartition
>;
479 (*this)["FASTBOOT:DELETE-LOGICAL-PARTITION"] = new_cmd_obj
<FBDelPartition
>;
480 (*this)["FB:RESIZE-LOGICAL-PARTITION"] = new_cmd_obj
<FBResizePartition
>;
481 (*this)["FASTBOOT:RESIZE-LOGICAL-PARTITION"] = new_cmd_obj
<FBResizePartition
>;
483 (*this)["FBK:UCMD"] = new_cmd_obj
<FBUCmd
>;
484 (*this)["FBK:ACMD"] = new_cmd_obj
<FBACmd
>;
485 (*this)["FBK:SYNC"] = new_cmd_obj
<FBSyncCmd
>;
486 (*this)["FBK:UCP"] = new_cmd_obj
<FBCopy
>;
488 (*this)["_ALL:DONE"] = new_cmd_obj
<CmdDone
>;
489 (*this)["_ALL:DELAY"] = new_cmd_obj
<CmdDelay
>;
490 (*this)["_ALL:SH"] = new_cmd_obj
<CmdShell
>;
491 (*this)["_ALL:SHELL"] = new_cmd_obj
<CmdShell
>;
492 (*this)["_ALL:<"] = new_cmd_obj
<CmdShell
>;
493 (*this)["_ALL:@"] = new_cmd_obj
<CmdEnv
>;
494 (*this)["_ALL:ERROR"] = new_cmd_obj
<CmdError
>;
495 (*this)["_ALL:IF"] = new_cmd_obj
<CmdIf
>;
499 shared_ptr
<CmdBase
> create_cmd_obj(string cmd
)
503 param
= get_next_param(cmd
, pos
, ':');
504 param
= remove_square_brackets(param
);
506 param
= str_to_upper(param
);
508 if (g_cmd_create_map
.find(param
) == g_cmd_create_map
.end())
511 param
= get_next_param(cmd
, pos
);
512 s
+= str_to_upper(param
);
513 if (g_cmd_create_map
.find(s
) != g_cmd_create_map
.end())
514 return g_cmd_create_map
[s
]((char*)cmd
.c_str());
516 string commoncmd
= "_ALL:";
517 commoncmd
+= str_to_upper(param
);
518 if (g_cmd_create_map
.find(commoncmd
) != g_cmd_create_map
.end())
519 return g_cmd_create_map
[commoncmd
]((char*)cmd
.c_str());
523 return g_cmd_create_map
[param
]((char*)cmd
.c_str());
527 err
= "Unknown Command:";
529 set_last_err_string(err
);
533 int uuu_run_cmd(const char * cmd
, int dry
)
535 return run_cmd(nullptr, cmd
, dry
);
538 int run_cmd(CmdCtx
*pCtx
, const char * cmd
, int dry
)
540 shared_ptr
<CmdBase
> p
;
541 p
= create_cmd_obj(cmd
);
548 nt
.type
= uuu_notify::NOTIFY_CMD_TOTAL
;
552 nt
.type
= uuu_notify::NOTIFY_CMD_START
;
553 nt
.str
= (char *)p
->get_cmd().c_str();
556 if (typeid(*p
) != typeid(CfgCmd
))
561 string pro
= get_next_param(c
, pos
, ':');
562 pro
= remove_square_brackets(pro
);
577 ret
= ctx
.look_for_match_device(pro
.c_str());
590 return ret
= dry
? p
->dump() : p
->run(nullptr);
593 nt
.type
= uuu_notify::NOTIFY_CMD_END
;
600 int CmdDone::run(CmdCtx
*)
603 nt
.type
= uuu_notify::NOTIFY_DONE
;
608 int CmdDelay::parser(char * /*p*/)
611 string param
= get_next_param(m_cmd
, pos
);
613 if (param
.find(':') != string::npos
)
614 param
= get_next_param(m_cmd
, pos
);
616 if (str_to_upper(param
) != "DELAY")
618 string err
= "Unknown Command:";
620 set_last_err_string(err
);
624 string ms
= get_next_param(m_cmd
, pos
);
625 m_ms
= str_to_uint32(ms
);
629 int CmdDelay::run(CmdCtx
*)
631 std::this_thread::sleep_for(std::chrono::milliseconds(m_ms
));
635 int CmdError::parser(char *p
)
643 if (parser_protocol(p
, pos
))
646 s
= get_next_param(m_cmd
, pos
);
648 m_error
= m_cmd
.substr(pos
);
653 int CmdError::run(CmdCtx
* /*pCtx*/)
655 set_last_err_string(m_error
);
659 int CmdShell::parser(char * p
)
667 if (parser_protocol(p
, pos
))
670 m_protocol
= m_cmd
.substr(0, pos
);
672 s
= get_next_param(m_cmd
, pos
);
676 if (pos
!= string::npos
&& pos
< m_cmd
.size())
677 m_shellcmd
= m_cmd
.substr(pos
);
682 int CmdShell::run(CmdCtx
*pCtx
)
686 #define _pclose pclose
688 FILE *pipe
= _popen(m_shellcmd
.c_str(), "r");
692 string err
= "failure popen: ";
693 err
+= m_shellcmd
.c_str();
694 set_last_err_string(err
);
700 while (fgets((char*)str
.c_str(), str
.size(), pipe
))
706 str
.resize(strlen(str
.c_str()));
710 size_t pos
= cmd
.find_first_of("\r\n");
711 if (pos
!= string::npos
)
712 cmd
= cmd
.substr(0, pos
);
714 return run_cmd(pCtx
, cmd
.c_str(), 0);
717 nt
.type
= uuu_notify::NOTIFY_CMD_INFO
;
718 nt
.str
= (char*)str
.c_str();
722 /* Close pipe and print return value of pPipe. */
725 int ret
= _pclose(pipe
);
727 str
.format("\nProcess returned %d\n", ret
);;
730 set_last_err_string(str
.c_str());
736 set_last_err_string("Error: Failed to read the end of the pipe.\n");
743 int CmdEnv::parser(char *p
)
750 if (parser_protocol(p
, pos
))
752 if (pos
== string::npos
|| pos
>= m_cmd
.size())
755 m_unfold_cmd
= m_cmd
.substr(0, pos
);
756 m_unfold_cmd
.append(" ");
759 get_next_param(m_cmd
, pos
);
761 auto cmd
= m_cmd
.substr(pos
);
763 regex expr
{ "@[0-9a-zA-Z_]+@" };
765 auto last_pos
= static_cast<const string
&>(cmd
).begin();
766 auto cmd_end
= static_cast<const string
&>(cmd
).end();
767 while (regex_search(last_pos
, cmd_end
, result
, expr
)) {
768 for (auto &i
: result
) {
769 string key
{ i
.first
+ 1, i
.second
- 1 };
770 auto value
= [&key
]() -> pair
<bool, string
> {
772 auto ptr
= getenv(key
.c_str());
778 getenv_s(&len
, nullptr, 0, key
.c_str());
780 /* To have the same behavior as Linux when uuu is provided with variables in the way : -e var=
781 * We return null char as windows cannot store empty environment variables
785 string
value(len
-1, '\0');
786 getenv_s(&len
, &value
[0], len
, key
.c_str());
787 return {true, value
};
791 set_last_err_string("variable '" + key
+ "' is not defined");
794 auto begin
= value
.second
.begin();
795 auto end
= value
.second
.end();
796 auto pos
= find_if(begin
, end
, [](char c
){ return c
== '\r' || c
== '\n'; });
797 m_unfold_cmd
.append(&*last_pos
, distance(last_pos
, i
.first
));
798 m_unfold_cmd
.append(begin
, pos
);
803 if(last_pos
!= cmd
.end())
804 m_unfold_cmd
.append(&*last_pos
);
809 int CmdIf::parser(char *p
)
818 if (parser_protocol(p
, pos
))
821 m_protocol
= m_cmd
.substr(0, pos
);
823 if (pos
== string::npos
|| pos
>= m_cmd
.size())
826 s
= get_next_param(m_cmd
, pos
);
827 if (str_to_upper(s
) != "IF")
829 string err
= "Unknown command: ";
831 set_last_err_string(s
);
835 get_next_param(m_cmd
, pos
);
837 size_t end
= m_cmd
.find("then", pos
);
839 if (end
== string::npos
)
841 set_last_err_string("missed key word: then");
845 m_condition
= m_cmd
.substr(lc
, end
- lc
);
846 m_true_cmd
= m_cmd
.substr(end
+ 4);
850 void CmdIf::build_map(CmdCtx
*p
)
854 s
.format("0x%04X", p
->m_config_item
->m_vid
);
855 insert_env_variable("@VID@", s
);
857 s
.format("0x%04X", p
->m_config_item
->m_pid
);
858 insert_env_variable("@PID@", s
);
860 s
.format("0x%04X", p
->m_current_bcd
);
861 insert_env_variable("@BCD@", s
);
863 insert_env_variable("@CHIP@", p
->m_config_item
->m_chip
);
867 int CmdIf::run(CmdCtx
*p
)
870 string cmp
[] = { "==", "!=", "" };
872 for (i
= 0; !cmp
[i
].empty(); i
++)
874 size_t pos
= m_condition
.find(cmp
[i
], 0);
875 if (pos
!= string::npos
)
877 l
= m_condition
.substr(0, pos
);
878 r
= m_condition
.substr(pos
+ cmp
[i
].size() + 1);
882 l
= str_to_upper(trim(l
));
883 r
= str_to_upper(trim(r
));
888 l
= get_env_variable(l
);
891 r
= get_env_variable(r
);
904 set_last_err_string("unknown if condition");
908 //Pass condition check;
909 string cmd
= m_protocol
;
911 cmd
+= this->m_true_cmd
;
912 return run_cmd(p
, cmd
.c_str(), 0);
915 int CmdEnv::run(CmdCtx
*p
)
917 return run_cmd(p
, m_unfold_cmd
.c_str(), 0);
920 int run_cmds(const char *protocol
, CmdCtx
*p
)
922 CmdMap cmdmap
, *pCmdMap
;
924 if (!g_cmd_list_file
.empty())
926 shared_ptr
<FileBuffer
> pin
= get_file_buffer(g_cmd_list_file
);
930 shared_ptr
<DataBuffer
> pbuff
= pin
->request_data(0, UINT64_MAX
);
933 if(parser_cmd_list_file(pbuff
, &cmdmap
))
939 pCmdMap
= &g_cmd_map
;
942 if (pCmdMap
->find(protocol
) == pCmdMap
->end())
947 return (*pCmdMap
)[protocol
]->run_all(p
);
950 static int insert_one_cmd(const char * cmd
, CmdMap
*pCmdMap
)
955 string pro
= get_next_param(s
, pos
, ':');
956 pro
= remove_square_brackets(pro
);
959 pro
= str_to_upper(pro
);
961 shared_ptr
<CmdBase
> p
= create_cmd_obj(s
);
968 if (pCmdMap
->find(pro
) == pCmdMap
->end())
970 shared_ptr
<CmdList
> list(new CmdList
);
971 (*pCmdMap
)[pro
] = list
;
974 (*pCmdMap
)[pro
]->push_back(p
);
980 static int added_default_boot_cmd(const char *filename
)
984 str
= "SDPS: boot -f ";
989 int ret
= insert_one_cmd(str
.c_str(), &g_cmd_map
);
992 insert_one_cmd("SDPS: done", &g_cmd_map
);
994 str
= "SDP: boot -f ";
999 ret
= insert_one_cmd(str
.c_str(), &g_cmd_map
);
1000 if (ret
) return ret
;
1002 insert_one_cmd("SDP: done", &g_cmd_map
);
1004 str
= "SDPU: write -f ";
1008 str
+= " -offset 0x57c00";
1009 insert_one_cmd(str
.c_str(), &g_cmd_map
);
1010 insert_one_cmd("SDPU: jump", &g_cmd_map
);
1011 insert_one_cmd("SDPU: done", &g_cmd_map
);
1013 str
= "SDPV: write -f ";
1018 insert_one_cmd(str
.c_str(), &g_cmd_map
);
1019 insert_one_cmd("SDPV: jump", &g_cmd_map
);
1020 insert_one_cmd("SDPV: done", &g_cmd_map
);
1025 int check_version(string str
)
1029 for (size_t i
= 0; i
< str
.size(); i
++)
1032 if (c
>= '0' && c
<= '9')
1037 if (c
== '.' || i
== str
.size()-1 || c
== '\n')
1045 int cur
= uuu_get_version();
1050 str
= "This version of uuu is too old, please download the latest one";
1051 set_last_err_string(str
);
1057 int uuu_run_cmd_script(const char * buff
, int /*dry*/)
1059 shared_ptr
<DataBuffer
> p(new DataBuffer((void*)buff
, strlen(buff
)));
1061 return parser_cmd_list_file(p
);
1064 int parser_cmd_list_file(shared_ptr
<DataBuffer
> pbuff
, CmdMap
*pCmdMap
)
1066 char uuu_version
[] = "uuu_version";
1069 if (pCmdMap
== nullptr)
1070 pCmdMap
= &g_cmd_map
;
1074 for (size_t i
= 0; i
< pbuff
->size(); i
++)
1076 uint8_t c
= pbuff
->at(i
);
1083 if (c
== '\n' || c
== 0 || i
== pbuff
->size() - 1)
1085 if (str
.substr(0, strlen(uuu_version
)) == uuu_version
)
1087 if (check_version(str
.substr(strlen(uuu_version
), 10)))
1091 }else if (str
.size() > 1)
1094 if (insert_one_cmd(str
.c_str(), pCmdMap
))
1103 int uuu_auto_detect_file(const char *filename
)
1106 fn
+= remove_quota(filename
);
1107 fn
.replace('\\', '/');
1115 shared_ptr
<FileBuffer
> buffer
= get_file_buffer(fn
);
1116 if (buffer
== nullptr)
1120 size_t pos
= str_to_upper(fn
).find("ZIP");
1121 if(pos
== string::npos
|| pos
!= fn
.size() - 3)
1123 pos
= str_to_upper(fn
).find("SDCARD");
1124 if (pos
== string::npos
|| pos
!= fn
.size() - 6)
1125 buffer
= get_file_buffer(fn
); //we don't try open a zip file here
1128 if(buffer
== nullptr)
1132 string str
= "uuu_version";
1133 shared_ptr
<DataBuffer
> pData
= buffer
->request_data(0, UINT_MAX
);
1136 void *p1
= pData
->data();
1137 void *p2
= (void*)str
.data();
1138 if (memcmp(p1
, p2
, str
.size()) == 0)
1140 size_t pos
= fn
.rfind('/');
1141 if (pos
!= string::npos
)
1142 set_current_dir(fn
.substr(0, pos
+ 1));
1144 g_cmd_list_file
= fn
.substr(pos
+1);
1146 return parser_cmd_list_file(pData
);
1149 //flash.bin or uboot.bin
1150 return added_default_boot_cmd(fn
.c_str());
1153 int notify_done(uuu_notify nt
, void *p
)
1155 if(nt
.type
== uuu_notify::NOTIFY_DONE
)
1156 *(std::atomic
<int> *) p
= 1;
1157 if (nt
.type
== uuu_notify::NOTIFY_CMD_END
&& nt
.status
)
1158 *(std::atomic
<int> *) p
= 1;
1162 int uuu_wait_uuu_finish(int deamon
, int dry
)
1164 std::atomic
<int> exit
;
1168 for(auto it
=g_cmd_map
.begin(); it
!= g_cmd_map
.end(); it
++)
1170 for(auto cmd
= it
->second
->begin(); cmd
!= it
->second
->end(); cmd
++)
1179 uuu_register_notify_callback(notify_done
, &exit
);
1181 if(polling_usb(exit
))