I understand that if a source file need to reference functions from other file then it needs to include its header file, but I don\'t understand why the source file include
Yours seems a borderline case, but an include file can be viewed as a sort of contract between that source file and any other source files that may require those functions.
By writing the "contract" in a header file, you can ensure that the other source files will know how to invoke those functions, or, rather, you will be sure that the compiler will insert the correct code and check its validity at compile time.
But what if you then (even inadvertently) changed the function prototype in the corresponding source file?
By including in that file the same header as everyone else, you will be warned at compile time should a change inadvertently "break" the contract.
Update (from @tmlen's comment): even if in this case it does not, an include file may also use declarations and pragmas such as #defines, typedef, enum, struct and inline as well as compiler macros, that would make no sense writing more than once (actually that would be dangerous to write in two different places, lest the copies get out of sync with each other with disastrous results). Some of those (e.g. a structure padding pragma) could become bugs difficult to track down.